summaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2022-11-05 18:23:30 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2022-11-05 18:23:30 +0000
commit4ed089396bc7f14bcb94e80f0f9f4757fd8c48b7 (patch)
tree866986558761a9709a7af1940ba607128a45f775 /plugins
parentReleasing debian version 2.1.2-2. (diff)
downloadnvme-cli-4ed089396bc7f14bcb94e80f0f9f4757fd8c48b7.tar.xz
nvme-cli-4ed089396bc7f14bcb94e80f0f9f4757fd8c48b7.zip
Merging upstream version 2.2.1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'plugins')
-rw-r--r--plugins/dera/dera-nvme.c15
-rw-r--r--plugins/innogrit/innogrit-nvme.c92
-rw-r--r--plugins/innogrit/typedef.h8
-rw-r--r--plugins/intel/intel-nvme.c144
-rw-r--r--plugins/memblaze/memblaze-nvme.c138
-rw-r--r--plugins/micron/micron-nvme.c308
-rw-r--r--plugins/netapp/netapp-nvme.c5
-rw-r--r--plugins/ocp/ocp-nvme.c67
-rw-r--r--plugins/scaleflux/sfx-nvme.c149
-rw-r--r--plugins/seagate/seagate-diag.h258
-rw-r--r--plugins/seagate/seagate-nvme.c1053
-rw-r--r--plugins/seagate/seagate-nvme.h23
-rw-r--r--plugins/shannon/shannon-nvme.c56
-rw-r--r--plugins/solidigm/meson.build2
-rw-r--r--plugins/solidigm/solidigm-garbage-collection.c28
-rw-r--r--plugins/solidigm/solidigm-latency-tracking.c27
-rw-r--r--plugins/solidigm/solidigm-nvme.c6
-rw-r--r--plugins/solidigm/solidigm-nvme.h3
-rw-r--r--plugins/solidigm/solidigm-smart.c27
-rw-r--r--plugins/solidigm/solidigm-telemetry.c183
-rw-r--r--plugins/solidigm/solidigm-telemetry.h8
-rw-r--r--plugins/solidigm/solidigm-telemetry/cod.c194
-rw-r--r--plugins/solidigm/solidigm-telemetry/cod.h9
-rw-r--r--plugins/solidigm/solidigm-telemetry/config.c44
-rw-r--r--plugins/solidigm/solidigm-telemetry/config.h10
-rw-r--r--plugins/solidigm/solidigm-telemetry/data-area.c424
-rw-r--r--plugins/solidigm/solidigm-telemetry/data-area.h11
-rw-r--r--plugins/solidigm/solidigm-telemetry/header.c199
-rw-r--r--plugins/solidigm/solidigm-telemetry/header.h9
-rw-r--r--plugins/solidigm/solidigm-telemetry/meson.build6
-rw-r--r--plugins/solidigm/solidigm-telemetry/telemetry-log.h31
-rw-r--r--plugins/toshiba/toshiba-nvme.c53
-rw-r--r--plugins/transcend/transcend-nvme.c25
-rw-r--r--plugins/virtium/virtium-nvme.c71
-rw-r--r--plugins/wdc/wdc-nvme.c1553
-rw-r--r--plugins/wdc/wdc-nvme.h2
-rw-r--r--plugins/ymtc/ymtc-nvme.c24
-rw-r--r--plugins/zns/zns.c244
38 files changed, 3803 insertions, 1706 deletions
diff --git a/plugins/dera/dera-nvme.c b/plugins/dera/dera-nvme.c
index 1390be0..9408e50 100644
--- a/plugins/dera/dera-nvme.c
+++ b/plugins/dera/dera-nvme.c
@@ -117,20 +117,21 @@ static int nvme_dera_get_device_status(int fd, enum dera_device_status *result)
static int get_status(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- int fd, err;
struct nvme_dera_smart_info_log log;
enum dera_device_status state = DEVICE_STATUS_FATAL_ERROR;
char *desc = "Get the Dera device status";
+ struct nvme_dev *dev;
+ int err;
OPT_ARGS(opts) = {
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
- err = nvme_get_log_simple(fd, 0xc0, sizeof(log), &log);
+ err = nvme_get_log_simple(dev_fd(dev), 0xc0, sizeof(log), &log);
if (err) {
goto exit;
}
@@ -153,7 +154,7 @@ static int get_status(int argc, char **argv, struct command *cmd, struct plugin
"Runtime Low",
};
- err = nvme_dera_get_device_status(fd, &state);
+ err = nvme_dera_get_device_status(dev_fd(dev), &state);
if (!err){
if (state > 0 && state < 4){
printf("device_status : %s %d%% completed\n", dev_status[state], log.rebuild_percent);
@@ -205,7 +206,7 @@ exit:
if (err > 0)
nvme_show_status(err);
- close(fd);
+ dev_close(dev);
return err;
}
diff --git a/plugins/innogrit/innogrit-nvme.c b/plugins/innogrit/innogrit-nvme.c
index 220a5a7..b5d40dd 100644
--- a/plugins/innogrit/innogrit-nvme.c
+++ b/plugins/innogrit/innogrit-nvme.c
@@ -5,6 +5,7 @@
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
+#include <time.h>
#include "common.h"
#include "nvme.h"
@@ -20,10 +21,11 @@ static int innogrit_smart_log_additional(int argc, char **argv,
struct plugin *plugin)
{
struct nvme_smart_log smart_log = { 0 };
- int fd, i, iindex;
struct vsc_smart_log *pvsc_smart = (struct vsc_smart_log *)smart_log.rsvd232;
const char *desc = "Retrieve additional SMART log for the given device ";
const char *namespace = "(optional) desired namespace";
+ struct nvme_dev *dev;
+ int err, i, iindex;
struct config {
__u32 namespace_id;
@@ -38,12 +40,12 @@ static int innogrit_smart_log_additional(int argc, char **argv,
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
- nvme_get_log_smart(fd, cfg.namespace_id, false, &smart_log);
- nvme_show_smart_log(&smart_log, cfg.namespace_id, devicename, NORMAL);
+ nvme_get_log_smart(dev_fd(dev), cfg.namespace_id, false, &smart_log);
+ nvme_show_smart_log(&smart_log, cfg.namespace_id, dev->name, NORMAL);
printf("DW0[0-1] Defect Cnt : %u\n", pvsc_smart->defect_cnt);
printf("DW0[2-3] Slc Spb Cnt : %u\n", pvsc_smart->slc_spb_cnt);
@@ -69,11 +71,15 @@ static int innogrit_smart_log_additional(int argc, char **argv,
printf("DW17 weight_ec : %u\n", pvsc_smart->weight_ec);
printf("DW18 slc_cap_mb : %u\n", pvsc_smart->slc_cap_mb);
printf("DW19-20 nand_page_write_cnt : %llu\n", pvsc_smart->nand_page_write_cnt);
-
- iindex = 21;
- for (i = 0; i < (sizeof(pvsc_smart->reserved2)/4); i++) {
- if (pvsc_smart->reserved2[i] != 0)
- printf("DW%-37d : %u\n", iindex, pvsc_smart->reserved2[i]);
+ printf("DW21 program_error_cnt : %u\n", pvsc_smart->program_error_cnt);
+ printf("DW22 erase_error_cnt : %u\n", pvsc_smart->erase_error_cnt);
+ printf("DW23[0] flash_type : %u\n", pvsc_smart->flash_type);
+ printf("DW24 hs_crc_err_cnt : %u\n", pvsc_smart->hs_crc_err_cnt);
+ printf("DW25 ddr_ecc_err_cnt : %u\n", pvsc_smart->ddr_ecc_err_cnt);
+ iindex = 26;
+ for (i = 0; i < (sizeof(pvsc_smart->reserved3)/4); i++) {
+ if (pvsc_smart->reserved3[i] != 0)
+ printf("DW%-37d : %u\n", iindex, pvsc_smart->reserved3[i]);
iindex++;
}
@@ -163,9 +169,10 @@ static int innogrit_vsc_geteventlog(int argc, char **argv,
unsigned int isize, icheck_stopvalue, iend;
unsigned char bSortLog = false, bget_nextlog = true;
struct evlg_flush_hdr *pevlog = (struct evlg_flush_hdr *)data;
- int fd, ret = -1;
const char *desc = "Recrieve event log for the given device ";
const char *clean_opt = "(optional) 1 for clean event log";
+ struct nvme_dev *dev;
+ int ret = -1;
struct config {
__u32 clean_flg;
@@ -180,9 +187,9 @@ static int innogrit_vsc_geteventlog(int argc, char **argv,
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
+ if (ret)
+ return ret;
if (getcwd(currentdir, 128) == NULL)
@@ -211,8 +218,10 @@ static int innogrit_vsc_geteventlog(int argc, char **argv,
icount++;
memset(data, 0, 4096);
- ret = nvme_vucmd(fd, NVME_VSC_GET_EVENT_LOG, 0, 0, (SRB_SIGNATURE >> 32),
- (SRB_SIGNATURE & 0xFFFFFFFF), (char *)data, 4096);
+ ret = nvme_vucmd(dev_fd(dev), NVME_VSC_GET_EVENT_LOG, 0, 0,
+ (SRB_SIGNATURE >> 32),
+ (SRB_SIGNATURE & 0xFFFFFFFF),
+ (char *)data, 4096);
if (ret == -1)
return ret;
@@ -277,10 +286,13 @@ static int innogrit_vsc_geteventlog(int argc, char **argv,
if (cfg.clean_flg == 1) {
printf("Clean eventlog\n");
- nvme_vucmd(fd, NVME_VSC_CLEAN_EVENT_LOG, 0, 0, (SRB_SIGNATURE >> 32),
- (SRB_SIGNATURE & 0xFFFFFFFF), (char *)NULL, 0);
+ nvme_vucmd(dev_fd(dev), NVME_VSC_CLEAN_EVENT_LOG, 0, 0,
+ (SRB_SIGNATURE >> 32),
+ (SRB_SIGNATURE & 0xFFFFFFFF), (char *)NULL, 0);
}
+ dev_close(dev);
+
return ret;
}
@@ -296,16 +308,17 @@ static int innogrit_vsc_getcdump(int argc, char **argv, struct command *command,
unsigned char busevsc = false;
unsigned int ipackcount, ipackindex;
char fwvera[32];
- int fd, ret = -1;
const char *desc = "Recrieve cdump data for the given device ";
+ struct nvme_dev *dev;
+ int ret = -1;
OPT_ARGS(opts) = {
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
+ if (ret)
+ return ret;
if (getcwd(currentdir, 128) == NULL)
return -1;
@@ -315,8 +328,9 @@ static int innogrit_vsc_getcdump(int argc, char **argv, struct command *command,
ipackindex = 0;
memset(data, 0, 4096);
- if (nvme_vucmd(fd, NVME_VSC_GET, VSC_FN_GET_CDUMP, 0x00, (SRB_SIGNATURE >> 32),
- (SRB_SIGNATURE & 0xFFFFFFFF), (char *)data, 4096) == 0) {
+ if (nvme_vucmd(dev_fd(dev), NVME_VSC_GET, VSC_FN_GET_CDUMP, 0x00,
+ (SRB_SIGNATURE >> 32), (SRB_SIGNATURE & 0xFFFFFFFF),
+ (char *)data, 4096) == 0) {
memcpy(&cdumpinfo, &data[3072], sizeof(cdumpinfo));
if (cdumpinfo.sig == 0x5a5b5c5d) {
busevsc = true;
@@ -337,7 +351,9 @@ static int innogrit_vsc_getcdump(int argc, char **argv, struct command *command,
if (busevsc == false) {
memset(data, 0, 4096);
- ret = nvme_get_nsid_log(fd, true, 0x07, NVME_NSID_ALL, 4096, data);
+ ret = nvme_get_nsid_log(dev_fd(dev), true, 0x07,
+ NVME_NSID_ALL,
+ 4096, data);
if (ret != 0)
return ret;
@@ -360,10 +376,15 @@ static int innogrit_vsc_getcdump(int argc, char **argv, struct command *command,
for (icur = 0; icur < itotal; icur += 4096) {
memset(data, 0, 4096);
if (busevsc)
- ret = nvme_vucmd(fd, NVME_VSC_GET, VSC_FN_GET_CDUMP, 0x00, (SRB_SIGNATURE >> 32),
- (SRB_SIGNATURE & 0xFFFFFFFF), (char *)data, 4096);
+ ret = nvme_vucmd(dev_fd(dev), NVME_VSC_GET,
+ VSC_FN_GET_CDUMP, 0x00,
+ (SRB_SIGNATURE >> 32),
+ (SRB_SIGNATURE & 0xFFFFFFFF),
+ (char *)data, 4096);
else
- ret = nvme_get_nsid_log(fd, true, 0x07, NVME_NSID_ALL, 4096, data);
+ ret = nvme_get_nsid_log(dev_fd(dev), true,
+ 0x07,
+ NVME_NSID_ALL, 4096, data);
if (ret != 0)
return ret;
@@ -379,10 +400,16 @@ static int innogrit_vsc_getcdump(int argc, char **argv, struct command *command,
if (ipackindex != ipackcount) {
memset(data, 0, 4096);
if (busevsc)
- ret = nvme_vucmd(fd, NVME_VSC_GET, VSC_FN_GET_CDUMP, 0x00, (SRB_SIGNATURE >> 32),
- (SRB_SIGNATURE & 0xFFFFFFFF), (char *)data, 4096);
+ ret = nvme_vucmd(dev_fd(dev), NVME_VSC_GET,
+ VSC_FN_GET_CDUMP, 0x00,
+ (SRB_SIGNATURE >> 32),
+ (SRB_SIGNATURE & 0xFFFFFFFF),
+ (char *)data, 4096);
else
- ret = nvme_get_nsid_log(fd, true, 0x07, NVME_NSID_ALL, 4096, data);
+ ret = nvme_get_nsid_log(dev_fd(dev), true,
+ 0x07,
+ NVME_NSID_ALL, 4096,
+ data);
if (ret != 0)
return ret;
@@ -398,5 +425,6 @@ static int innogrit_vsc_getcdump(int argc, char **argv, struct command *command,
}
printf("\n");
+ dev_close(dev);
return ret;
}
diff --git a/plugins/innogrit/typedef.h b/plugins/innogrit/typedef.h
index d4ea269..a97a008 100644
--- a/plugins/innogrit/typedef.h
+++ b/plugins/innogrit/typedef.h
@@ -56,7 +56,13 @@ struct vsc_smart_log {
unsigned int weight_ec;
unsigned int slc_cap_mb;
unsigned long long nand_page_write_cnt;
- unsigned int reserved2[49];
+ unsigned int program_error_cnt;
+ unsigned int erase_error_cnt;
+ u_char flash_type;
+ u_char reserved2[3];
+ unsigned int hs_crc_err_cnt;
+ unsigned int ddr_ecc_err_cnt;
+ unsigned int reserved3[44];
};
#pragma pack(pop)
diff --git a/plugins/intel/intel-nvme.c b/plugins/intel/intel-nvme.c
index 1bf6627..f660b84 100644
--- a/plugins/intel/intel-nvme.c
+++ b/plugins/intel/intel-nvme.c
@@ -344,7 +344,8 @@ static int get_additional_smart_log(int argc, char **argv, struct command *cmd,
const char *json= "Dump output in json format";
struct nvme_additional_smart_log smart_log;
- int err, fd;
+ struct nvme_dev *dev;
+ int err;
struct config {
__u32 namespace_id;
@@ -363,22 +364,25 @@ static int get_additional_smart_log(int argc, char **argv, struct command *cmd,
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
- err = nvme_get_log_simple(fd, 0xca, sizeof(smart_log), &smart_log);
+ err = nvme_get_log_simple(dev_fd(dev), 0xca, sizeof(smart_log),
+ &smart_log);
if (!err) {
if (cfg.json)
- show_intel_smart_log_jsn(&smart_log, cfg.namespace_id, devicename);
+ show_intel_smart_log_jsn(&smart_log, cfg.namespace_id,
+ dev->name);
else if (!cfg.raw_binary)
- show_intel_smart_log(&smart_log, cfg.namespace_id, devicename);
+ show_intel_smart_log(&smart_log, cfg.namespace_id,
+ dev->name);
else
d_raw((unsigned char *)&smart_log, sizeof(smart_log));
}
else if (err > 0)
nvme_show_status(err);
- close(fd);
+ dev_close(dev);
return err;
}
@@ -386,9 +390,9 @@ static int get_market_log(int argc, char **argv, struct command *cmd, struct plu
{
const char *desc = "Get Intel Marketing Name log and show it.";
const char *raw = "dump output in binary format";
-
+ struct nvme_dev *dev;
char log[512];
- int err, fd;
+ int err;
struct config {
bool raw_binary;
@@ -402,11 +406,11 @@ static int get_market_log(int argc, char **argv, struct command *cmd, struct plu
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
- err = nvme_get_log_simple(fd, 0xdd, sizeof(log), log);
+ err = nvme_get_log_simple(dev_fd(dev), 0xdd, sizeof(log), log);
if (!err) {
if (!cfg.raw_binary)
printf("Intel Marketing Name Log:\n%s\n", log);
@@ -414,7 +418,7 @@ 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);
- close(fd);
+ dev_close(dev);
return err;
}
@@ -447,7 +451,8 @@ static void show_temp_stats(struct intel_temp_stats *stats)
static int get_temp_stats_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
struct intel_temp_stats stats;
- int err, fd;
+ struct nvme_dev *dev;
+ int err;
const char *desc = "Get Temperature Statistics log and show it.";
const char *raw = "dump output in binary format";
@@ -463,11 +468,11 @@ static int get_temp_stats_log(int argc, char **argv, struct command *cmd, struct
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
- err = nvme_get_log_simple(fd, 0xc5, sizeof(stats), &stats);
+ err = nvme_get_log_simple(dev_fd(dev), 0xc5, sizeof(stats), &stats);
if (!err) {
if (!cfg.raw_binary)
show_temp_stats(&stats);
@@ -475,7 +480,7 @@ 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);
- close(fd);
+ dev_close(dev);
return err;
}
@@ -1024,9 +1029,9 @@ static void show_lat_stats(int write)
static int get_lat_stats_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
-
- int err, fd;
__u8 data[NAND_LAT_STATS_LEN];
+ struct nvme_dev *dev;
+ int err;
const char *desc = "Get Intel Latency Statistics log and show it.";
const char *raw = "Dump output in binary format";
@@ -1049,15 +1054,15 @@ static int get_lat_stats_log(int argc, char **argv, struct command *cmd, struct
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ err = parse_and_open(&dev, 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(fd, cfg.write ? 0xc2 : 0xc1,
- sizeof(data), &data);
+ err = nvme_get_log_simple(dev_fd(dev), cfg.write ? 0xc2 : 0xc1,
+ sizeof(data), &data);
media_version[0] = (data[1] << 8) | data[0];
media_version[1] = (data[3] << 8) | data[2];
@@ -1071,7 +1076,7 @@ static int get_lat_stats_log(int argc, char **argv, struct command *cmd, struct
struct nvme_get_features_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.fid = 0xf7,
.nsid = 0,
.sel = 0,
@@ -1123,7 +1128,7 @@ static int get_lat_stats_log(int argc, char **argv, struct command *cmd, struct
}
close_fd:
- close(fd);
+ dev_close(dev);
return err;
}
@@ -1338,13 +1343,14 @@ static int get_internal_log(int argc, char **argv, struct command *command,
{
__u8 buf[0x2000];
char f[0x100];
- int err, fd, output, i, j, count = 0, core_num = 1;
+ int err, output, i, j, count = 0, core_num = 1;
struct nvme_passthru_cmd cmd;
struct intel_cd_log cdlog;
struct intel_vu_log *intel = malloc(sizeof(struct intel_vu_log));
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;
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.";
@@ -1380,10 +1386,10 @@ static int get_internal_log(int argc, char **argv, struct command *command,
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0) {
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err) {
free(intel);
- return fd;
+ return err;
}
if (cfg.log > 2 || cfg.core > 4 || cfg.lnum > 255) {
@@ -1392,7 +1398,7 @@ static int get_internal_log(int argc, char **argv, struct command *command,
}
if (!cfg.file) {
- err = setup_file(f, cfg.file, fd, cfg.log);
+ err = setup_file(f, cfg.file, dev_fd(dev), cfg.log);
if (err)
goto out_free;
cfg.file = f;
@@ -1410,7 +1416,8 @@ static int get_internal_log(int argc, char **argv, struct command *command,
goto out_free;
}
- err = read_header(&cmd, buf, fd, cdlog.u.entireDword, cfg.namespace_id);
+ err = read_header(&cmd, buf, dev_fd(dev), cdlog.u.entireDword,
+ cfg.namespace_id);
if (err)
goto out;
memcpy(intel, buf, sizeof(*intel));
@@ -1419,7 +1426,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, fd, &cmd);
+ err = get_internal_log_old(buf, output, dev_fd(dev), &cmd);
goto out;
}
@@ -1463,7 +1470,9 @@ static int get_internal_log(int argc, char **argv, struct command *command,
cmd.cdw10 = 0x400;
cmd.data_len = min(0x400, ad[i].assertsize) * 4;
err = read_entire_cmd(&cmd, ad[i].assertsize,
- 0x400, output, fd, buf);
+ 0x400, output,
+ dev_fd(dev),
+ buf);
if (err)
goto out;
@@ -1472,8 +1481,9 @@ 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, fd, cdlog.u.entireDword,
- cfg.namespace_id);
+ err = read_header(&cmd, buf, dev_fd(dev),
+ cdlog.u.entireDword,
+ cfg.namespace_id);
if (err)
goto out;
err = write_header(buf, output, sizeof(*intel_nlog));
@@ -1485,7 +1495,9 @@ static int get_internal_log(int argc, char **argv, struct command *command,
cmd.cdw10 = 0x400;
cmd.data_len = min(0x1000, intel_nlog->nlogbytesize);
err = read_entire_cmd(&cmd, intel_nlog->nlogbytesize / 4,
- 0x400, output, fd, buf);
+ 0x400, output,
+ dev_fd(dev),
+ buf);
if (err)
goto out;
} else if (cfg.log == 1) {
@@ -1493,7 +1505,9 @@ static int get_internal_log(int argc, char **argv, struct command *command,
cmd.cdw10 = 0x400;
cmd.data_len = 0x400;
err = read_entire_cmd(&cmd, ehdr->edumps[j].coresize,
- 0x400, output, fd, buf);
+ 0x400, output,
+ dev_fd(dev),
+ buf);
if (err)
goto out;
}
@@ -1511,14 +1525,13 @@ out:
close(output);
out_free:
free(intel);
- close(fd);
+ dev_close(dev);
return err;
}
static int enable_lat_stats_tracking(int argc, char **argv,
struct command *command, struct plugin *plugin)
{
- int err, fd;
const char *desc = (
"Enable/Disable Intel Latency Statistics Tracking.\n"
"No argument prints current status.");
@@ -1531,8 +1544,10 @@ static int enable_lat_stats_tracking(int argc, char **argv,
const __u32 cdw12 = 0x0;
const __u32 data_len = 32;
const __u32 save = 0;
- __u32 result;
+ struct nvme_dev *dev;
void *buf = NULL;
+ __u32 result;
+ int err;
struct config {
bool enable, disable;
@@ -1549,7 +1564,7 @@ static int enable_lat_stats_tracking(int argc, char **argv,
{NULL}
};
- fd = parse_and_open(argc, argv, desc, command_line_options);
+ err = parse_and_open(&dev, argc, argv, desc, command_line_options);
enum Option {
None = -1,
@@ -1564,12 +1579,12 @@ static int enable_lat_stats_tracking(int argc, char **argv,
else if (cfg.enable || cfg.disable)
option = cfg.enable;
- if (fd < 0)
- return fd;
+ if (err)
+ return err;
struct nvme_get_features_args args_get = {
.args_size = sizeof(args_get),
- .fd = fd,
+ .fd = dev_fd(dev),
.fid = fid,
.nsid = nsid,
.sel = sel,
@@ -1583,7 +1598,7 @@ static int enable_lat_stats_tracking(int argc, char **argv,
struct nvme_set_features_args args_set = {
.args_size = sizeof(args_set),
- .fd = fd,
+ .fd = dev_fd(dev),
.fid = fid,
.nsid = nsid,
.cdw11 = option,
@@ -1606,7 +1621,7 @@ static int enable_lat_stats_tracking(int argc, char **argv,
fid, result);
} else {
printf("Could not read feature id 0xE2.\n");
- close(fd);
+ dev_close(dev);
return err;
}
break;
@@ -1627,14 +1642,13 @@ static int enable_lat_stats_tracking(int argc, char **argv,
printf("%d not supported.\n", option);
return EINVAL;
}
- close(fd);
- return fd;
+ dev_close(dev);
+ return err;
}
static int set_lat_stats_thresholds(int argc, char **argv,
struct command *command, struct plugin *plugin)
{
- int err, fd, num;
const char *desc = "Write Intel Bucket Thresholds for Latency Statistics Tracking";
const char *bucket_thresholds = "Bucket Threshold List, comma separated list: 0, 10, 20 ...";
const char *write = "Set write bucket Thresholds for latency tracking (read default)";
@@ -1643,7 +1657,9 @@ static int set_lat_stats_thresholds(int argc, char **argv,
const __u8 fid = 0xf7;
const __u32 cdw12 = 0x0;
const __u32 save = 0;
+ struct nvme_dev *dev;
__u32 result;
+ int err, num;
struct config {
bool write;
@@ -1662,21 +1678,21 @@ static int set_lat_stats_thresholds(int argc, char **argv,
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
+ err = parse_and_open(&dev, argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ if (err)
+ return err;
/* Query maj and minor version first to figure out the amount of
* valid buckets a user is allowed to modify. Read or write doesn't
* matter
*/
- err = nvme_get_log_simple(fd, 0xc2,
- sizeof(media_version), media_version);
+ err = nvme_get_log_simple(dev_fd(dev), 0xc2,
+ sizeof(media_version), media_version);
if (err) {
fprintf(stderr, "Querying media version failed. ");
nvme_show_status(err);
- goto close_fd;
+ goto close_dev;
}
if (media_version[0] == 1000) {
@@ -1686,13 +1702,13 @@ static int set_lat_stats_thresholds(int argc, char **argv,
sizeof(thresholds));
if (num == -1) {
fprintf(stderr, "ERROR: Bucket list is malformed\n");
- goto close_fd;
+ goto close_dev;
}
struct nvme_set_features_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.fid = fid,
.nsid = nsid,
.cdw11 = cfg.write ? 0x1 : 0x0,
@@ -1717,8 +1733,8 @@ static int set_lat_stats_thresholds(int argc, char **argv,
fprintf(stderr, "Unsupported command\n");
}
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
return err;
}
diff --git a/plugins/memblaze/memblaze-nvme.c b/plugins/memblaze/memblaze-nvme.c
index a6a8ddf..6fdd675 100644
--- a/plugins/memblaze/memblaze-nvme.c
+++ b/plugins/memblaze/memblaze-nvme.c
@@ -453,15 +453,16 @@ int parse_params(char *str, int number, ...)
static int mb_get_additional_smart_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
struct nvme_memblaze_smart_log smart_log;
- int err, fd;
char *desc = "Get Memblaze 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;
struct config {
__u32 namespace_id;
bool raw_binary;
};
+ int err;
struct config cfg = {
.namespace_id = NVME_NSID_ALL,
@@ -473,22 +474,24 @@ static int mb_get_additional_smart_log(int argc, char **argv, struct command *cm
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
- err = nvme_get_nsid_log(fd, false, 0xca, cfg.namespace_id,
- sizeof(smart_log), &smart_log);
+ err = nvme_get_nsid_log(dev_fd(dev), false, 0xca, cfg.namespace_id,
+ sizeof(smart_log), &smart_log);
if (!err) {
if (!cfg.raw_binary)
- err = show_memblaze_smart_log(fd, cfg.namespace_id, devicename, &smart_log);
+ err = show_memblaze_smart_log(dev_fd(dev),
+ cfg.namespace_id,
+ dev->name, &smart_log);
else
d_raw((unsigned char *)&smart_log, sizeof(smart_log));
}
if (err > 0)
nvme_show_status(err);
- close(fd);
+ dev_close(dev);
return err;
}
@@ -505,20 +508,22 @@ static char *mb_feature_to_string(int feature)
static int mb_get_powermanager_status(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
const char *desc = "Get Memblaze power management ststus\n (value 0 - 25w, 1 - 20w, 2 - 15w)";
- int err, fd;
__u32 result;
__u32 feature_id = MB_FEAT_POWER_MGMT;
+ struct nvme_dev *dev;
+ int err;
OPT_ARGS(opts) = {
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0) return fd;
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
struct nvme_get_features_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.fid = feature_id,
.nsid = 0,
.sel = 0,
@@ -539,7 +544,7 @@ static int mb_get_powermanager_status(int argc, char **argv, struct command *cmd
nvme_select_to_string(0), result);
} else if (err > 0)
nvme_show_status(err);
- close(fd);
+ dev_close(dev);
return err;
}
@@ -548,8 +553,9 @@ static int mb_set_powermanager_status(int argc, char **argv, struct command *cmd
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";
- int err, fd;
+ struct nvme_dev *dev;
__u32 result;
+ int err;
struct config {
__u32 feature_id;
@@ -569,12 +575,13 @@ static int mb_set_powermanager_status(int argc, char **argv, struct command *cmd
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0) return fd;
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
struct nvme_set_features_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.fid = cfg.feature_id,
.nsid = 0,
.cdw11 = cfg.value,
@@ -597,7 +604,7 @@ static int mb_set_powermanager_status(int argc, char **argv, struct command *cmd
} else if (err > 0)
nvme_show_status(err);
- close(fd);
+ dev_close(dev);
return err;
}
@@ -611,9 +618,10 @@ static int mb_set_high_latency_log(int argc, char **argv, struct command *cmd, s
" p1 value: 0 is disable, 1 is enable\n"\
" p2 value: 1 .. 5000 ms";
const char *param = "input parameters";
- int err, fd;
- __u32 result;
int param1 = 0, param2 = 0;
+ struct nvme_dev *dev;
+ __u32 result;
+ int err;
struct config {
__u32 feature_id;
@@ -632,24 +640,25 @@ static int mb_set_high_latency_log(int argc, char **argv, struct command *cmd, s
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0) return fd;
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
if (parse_params(cfg.param, 2, &param1, &param2)) {
printf("setfeature: invalid formats %s\n", cfg.param);
- close(fd);
+ dev_close(dev);
return EINVAL;
}
if ((param1 == 1) && (param2 < P2MIN || param2 > P2MAX)) {
printf("setfeature: invalid high io latency threshold %d\n", param2);
- close(fd);
+ dev_close(dev);
return EINVAL;
}
cfg.value = (param1 << MB_FEAT_HIGH_LATENCY_VALUE_SHIFT) | param2;
struct nvme_set_features_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.fid = cfg.feature_id,
.nsid = 0,
.cdw11 = cfg.value,
@@ -672,7 +681,7 @@ static int mb_set_high_latency_log(int argc, char **argv, struct command *cmd, s
} else if (err > 0)
nvme_show_status(err);
- close(fd);
+ dev_close(dev);
return err;
}
@@ -774,25 +783,29 @@ static int glp_high_latency(FILE *fdi, char *buf, int buflen, int print)
static int mb_high_latency_log_print(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
const char *desc = "Get Memblaze high latency log";
- int err, fd;
char buf[LOG_PAGE_SIZE];
+ struct nvme_dev *dev;
FILE *fdi = NULL;
+ int err;
OPT_ARGS(opts) = {
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0) return fd;
+ err = parse_and_open(&dev, 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(fd, GLP_ID_VU_GET_HIGH_LATENCY_LOG, sizeof(buf), &buf);
+ err = nvme_get_log_simple(dev_fd(dev), GLP_ID_VU_GET_HIGH_LATENCY_LOG,
+ sizeof(buf), &buf);
while (1) {
if (!glp_high_latency(fdi, buf, LOG_PAGE_SIZE, DO_PRINT_FLAG)) break;
- err = nvme_get_log_simple(fd, GLP_ID_VU_GET_HIGH_LATENCY_LOG, sizeof(buf), &buf);
+ err = nvme_get_log_simple(dev_fd(dev), GLP_ID_VU_GET_HIGH_LATENCY_LOG,
+ sizeof(buf), &buf);
if ( err) {
nvme_show_status(err);
break;
@@ -800,7 +813,7 @@ static int mb_high_latency_log_print(int argc, char **argv, struct command *cmd,
}
if (NULL != fdi) fclose(fdi);
- close(fd);
+ dev_close(dev);
return err;
}
@@ -829,7 +842,8 @@ static int mb_selective_download(int argc, char **argv, struct command *cmd, str
const char *select = "FW Select (e.g., --select=OOB, EEP, ALL)";
int xfer = 4096;
void *fw_buf;
- int fd, selectNo,fw_fd,fw_size,err,offset = 0;
+ int selectNo,fw_fd,fw_size,err,offset = 0;
+ struct nvme_dev *dev;
struct stat sb;
int i;
@@ -849,9 +863,9 @@ static int mb_selective_download(int argc, char **argv, struct command *cmd, str
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
if (strlen(cfg.select) != 3) {
fprintf(stderr, "Invalid select flag\n");
@@ -912,7 +926,7 @@ static int mb_selective_download(int argc, char **argv, struct command *cmd, str
struct nvme_fw_download_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.offset = offset,
.data_len = xfer,
.data = fw_buf,
@@ -932,7 +946,7 @@ static int mb_selective_download(int argc, char **argv, struct command *cmd, str
offset += xfer;
}
- err = memblaze_fw_commit(fd,selectNo);
+ err = memblaze_fw_commit(dev_fd(dev), selectNo);
if(err == 0x10B || err == 0x20B) {
err = 0;
@@ -944,7 +958,7 @@ out_free:
out_close:
close(fw_fd);
out:
- close(fd);
+ dev_close(dev);
return err;
}
@@ -1051,10 +1065,10 @@ int io_latency_histogram(char *file, char *buf, int print, int logid)
static int mb_lat_stats_log_print(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
char stats[LOG_PAGE_SIZE];
- int err = 0;
- int fd;
char f1[] = FID_C1_LOG_FILENAME;
char f2[] = FID_C2_LOG_FILENAME;
+ struct nvme_dev *dev;
+ int err;
const char *desc = "Get Latency Statistics log and show it.";
const char *write = "Get write statistics (read default)";
@@ -1071,17 +1085,19 @@ static int mb_lat_stats_log_print(int argc, char **argv, struct command *cmd, st
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0) return fd;
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
- err = nvme_get_log_simple(fd, cfg.write ? 0xc2 : 0xc1, sizeof(stats), &stats);
+ err = nvme_get_log_simple(dev_fd(dev), cfg.write ? 0xc2 : 0xc1,
+ sizeof(stats), &stats);
if (!err)
io_latency_histogram(cfg.write ? f2 : f1, stats, DO_PRINT_FLAG,
cfg.write ? GLP_ID_VU_GET_WRITE_LATENCY_HISTOGRAM : GLP_ID_VU_GET_READ_LATENCY_HISTOGRAM);
else
nvme_show_status(err);
- close(fd);
+ dev_close(dev);
return err;
}
@@ -1089,8 +1105,9 @@ static int mb_lat_stats_log_print(int argc, char **argv, struct command *cmd, st
#define FID 0x68
static int memblaze_clear_error_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- int err, fd;
char *desc = "Clear Memblaze devices error log.";
+ struct nvme_dev *dev;
+ int err;
//const char *value = "new value of feature (required)";
//const char *save = "specifies that the controller shall save the attribute";
@@ -1112,13 +1129,13 @@ static int memblaze_clear_error_log(int argc, char **argv, struct command *cmd,
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
struct nvme_set_features_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.fid = cfg.feature_id,
.nsid = 0,
.cdw11 = cfg.value,
@@ -1154,14 +1171,13 @@ static int memblaze_clear_error_log(int argc, char **argv, struct command *cmd,
printf("NVMe Status:%s(%x)\n", nvme_status_to_string(err), err);
};
*/
- close(fd);
+ dev_close(dev);
return err;
}
static int mb_set_lat_stats(int argc, char **argv,
struct command *command, struct plugin *plugin)
{
- int err, fd;
const char *desc = (
"Enable/Disable Latency Statistics Tracking.\n"
"No argument prints current status.");
@@ -1174,8 +1190,10 @@ static int mb_set_lat_stats(int argc, char **argv,
const __u32 cdw12 = 0x0;
const __u32 data_len = 32;
const __u32 save = 0;
- __u32 result;
+ struct nvme_dev *dev;
void *buf = NULL;
+ __u32 result;
+ int err;
struct config {
bool enable, disable;
@@ -1192,7 +1210,7 @@ static int mb_set_lat_stats(int argc, char **argv,
{NULL}
};
- fd = parse_and_open(argc, argv, desc, command_line_options);
+ err = parse_and_open(&dev, argc, argv, desc, command_line_options);
enum Option {
None = -1,
@@ -1208,7 +1226,7 @@ static int mb_set_lat_stats(int argc, char **argv,
struct nvme_get_features_args args_get = {
.args_size = sizeof(args_get),
- .fd = fd,
+ .fd = dev_fd(dev),
.fid = fid,
.nsid = nsid,
.sel = sel,
@@ -1222,7 +1240,7 @@ static int mb_set_lat_stats(int argc, char **argv,
struct nvme_set_features_args args_set = {
.args_size = sizeof(args_set),
- .fd = fd,
+ .fd = dev_fd(dev),
.fid = fid,
.nsid = nsid,
.cdw11 = option,
@@ -1236,8 +1254,8 @@ static int mb_set_lat_stats(int argc, char **argv,
.result = &result,
};
- if (fd < 0)
- return fd;
+ if (err)
+ return err;
switch (option) {
case None:
err = nvme_get_features(&args_get);
@@ -1247,7 +1265,7 @@ static int mb_set_lat_stats(int argc, char **argv,
fid, result);
} else {
printf("Could not read feature id 0xE2.\n");
- close(fd);
+ dev_close(dev);
return err;
}
break;
@@ -1268,7 +1286,7 @@ static int mb_set_lat_stats(int argc, char **argv,
printf("%d not supported.\n", option);
err = EINVAL;
}
- close(fd);
+ dev_close(dev);
return err;
}
diff --git a/plugins/micron/micron-nvme.c b/plugins/micron/micron-nvme.c
index 1c3c51d..e6f3a8c 100644
--- a/plugins/micron/micron-nvme.c
+++ b/plugins/micron/micron-nvme.c
@@ -453,13 +453,15 @@ exit_status:
/*
* Plugin Commands
*/
-static int micron_parse_options(int argc, char **argv, const char *desc,
- const struct argconfig_commandline_options *opts, eDriveModel *modelp)
+static int micron_parse_options(struct nvme_dev **dev, int argc, char **argv,
+ const char *desc,
+ const struct argconfig_commandline_options *opts,
+ eDriveModel *modelp)
{
int idx = 0;
- int fd = parse_and_open(argc, argv, desc, opts);
+ int err = parse_and_open(dev, argc, argv, desc, opts);
- if (fd < 0) {
+ if (err) {
perror("open");
return -1;
}
@@ -469,7 +471,7 @@ static int micron_parse_options(int argc, char **argv, const char *desc,
*modelp = GetDriveModel(idx);
}
- return fd;
+ return 0;
}
static int micron_fw_commit(int fd, int select)
@@ -496,7 +498,8 @@ static int micron_selective_download(int argc, char **argv,
const char *select = "FW Select (e.g., --select=ALL)";
int xfer = 4096;
void *fw_buf;
- int fd, selectNo, fw_fd, fw_size, err, offset = 0;
+ int selectNo, fw_fd, fw_size, err, offset = 0;
+ struct nvme_dev *dev;
struct stat sb;
struct config {
@@ -515,13 +518,13 @@ static int micron_selective_download(int argc, char **argv,
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
if (strlen(cfg.select) != 3) {
fprintf(stderr, "Invalid select flag\n");
- close(fd);
+ dev_close(dev);
return EINVAL;
}
@@ -537,14 +540,14 @@ static int micron_selective_download(int argc, char **argv,
selectNo = 26;
} else {
fprintf(stderr, "Invalid select flag\n");
- close(fd);
+ dev_close(dev);
return EINVAL;
}
fw_fd = open(cfg.fw, O_RDONLY);
if (fw_fd < 0) {
fprintf(stderr, "no firmware file provided\n");
- close(fd);
+ dev_close(dev);
return EINVAL;
}
@@ -578,7 +581,7 @@ static int micron_selective_download(int argc, char **argv,
struct nvme_fw_download_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.offset = offset,
.data_len = xfer,
.data = fw_buf,
@@ -598,7 +601,7 @@ static int micron_selective_download(int argc, char **argv,
offset += xfer;
}
- err = micron_fw_commit(fd, selectNo);
+ err = micron_fw_commit(dev_fd(dev), selectNo);
if (err == 0x10B || err == 0x20B) {
err = 0;
@@ -610,7 +613,7 @@ out_free:
free(fw_buf);
out:
close(fw_fd);
- close(fd);
+ dev_close(dev);
return err;
}
@@ -625,10 +628,10 @@ static int micron_smbus_option(int argc, char **argv,
"temperature (default) for enable option, 0 (current), "
"1 (default), 2 (saved) for status options";
const char *save = "1 - persistent, 0 - non-persistent (default)";
- int err = 0;
- int fd = 0;
int fid = MICRON_FEATURE_SMBUS_OPTION;
eDriveModel model = UNKNOWN_MODEL;
+ struct nvme_dev *dev;
+ int err = 0;
struct {
char *option;
@@ -649,18 +652,20 @@ static int micron_smbus_option(int argc, char **argv,
OPT_END()
};
- if ((fd = micron_parse_options(argc, argv, desc, opts, &model)) < 0)
+ err = micron_parse_options(&dev, argc, argv, desc, opts, &model);
+ if (err < 0)
return err;
if (model != M5407 && model != M5411) {
printf ("This option is not supported for specified drive\n");
- close(fd);
+ dev_close(dev);
return err;
}
if (!strcmp(opt.option, "enable")) {
cdw11 = opt.value << 1 | 1;
- err = nvme_set_features_simple(fd, fid, 1, cdw11, opt.save, &result);
+ err = nvme_set_features_simple(dev_fd(dev), fid, 1, cdw11, opt.save,
+ &result);
if (err == 0) {
printf("successfully enabled SMBus on drive\n");
} else {
@@ -670,7 +675,7 @@ static int micron_smbus_option(int argc, char **argv,
else if (!strcmp(opt.option, "status")) {
struct nvme_get_features_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.fid = fid,
.nsid = 1,
.sel = opt.value,
@@ -692,7 +697,8 @@ static int micron_smbus_option(int argc, char **argv,
}
else if (!strcmp(opt.option, "disable")) {
cdw11 = opt.value << 1 | 0;
- err = nvme_set_features_simple(fd, fid, 1, cdw11, opt.save, &result);
+ err = nvme_set_features_simple(dev_fd(dev), fid, 1, cdw11, opt.save,
+ &result);
if (err == 0) {
printf("Successfully disabled SMBus on drive\n");
} else {
@@ -701,11 +707,11 @@ static int micron_smbus_option(int argc, char **argv,
} else {
printf("Invalid option %s, valid values are enable, disable or status\n",
opt.option);
- close(fd);
+ dev_close(dev);
return -1;
}
- close(fd);
+ close(dev_fd(dev));
return err;
}
@@ -727,15 +733,15 @@ static int micron_temp_stats(int argc, char **argv, struct command *cmd,
bool is_json = false;
struct json_object *root;
struct json_object *logPages;
- int fd;
+ struct nvme_dev *dev;
OPT_ARGS(opts) = {
OPT_FMT("format", 'f', &cfg.fmt, fmt),
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0) {
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err) {
printf("\nDevice not found \n");;
return -1;
}
@@ -743,7 +749,7 @@ static int micron_temp_stats(int argc, char **argv, struct command *cmd,
if (strcmp(cfg.fmt, "json") == 0)
is_json = true;
- err = nvme_get_log_smart(fd, 0xffffffff, false, &smart_log);
+ err = nvme_get_log_smart(dev_fd(dev), 0xffffffff, false, &smart_log);
if (!err) {
temperature = ((smart_log.temperature[1] << 8) | smart_log.temperature[0]);
temperature = temperature ? temperature - 273 : 0;
@@ -778,15 +784,16 @@ static int micron_temp_stats(int argc, char **argv, struct command *cmd,
}
}
}
- close(fd);
+ dev_close(dev);
return err;
}
static int micron_pcie_stats(int argc, char **argv,
struct command *cmd, struct plugin *plugin)
{
- int i, fd, err = 0, bus = 0, domain = 0, device = 0, function = 0, ctrlIdx;
+ 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 *businfo = NULL;
char *devicename = NULL;
char tdevice[NAME_MAX] = { 0 };
@@ -875,8 +882,8 @@ static int micron_pcie_stats(int argc, char **argv,
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0) {
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err) {
printf("\nDevice not found \n");;
return -1;
}
@@ -896,7 +903,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(fd, &admin_cmd, NULL);
+ err = nvme_submit_admin_passthru(dev_fd(dev), &admin_cmd, NULL);
if (!err) {
counters = true;
correctable_errors = 10;
@@ -1017,8 +1024,7 @@ print_stats:
}
out:
- if (fd > 0)
- close(fd);
+ dev_close(dev);
return err;
}
@@ -1028,6 +1034,7 @@ static int micron_clear_pcie_correctable_errors(int argc, char **argv,
{
int err = -EINVAL, bus = 0, domain = 0, device = 0, function = 0;
char strTempFile[1024], strTempFile2[1024], command[1024];
+ struct nvme_dev *dev;
char *businfo = NULL;
char *devicename = NULL;
char tdevice[PATH_MAX] = { 0 };
@@ -1035,7 +1042,6 @@ static int micron_clear_pcie_correctable_errors(int argc, char **argv,
eDriveModel model = UNKNOWN_MODEL;
struct nvme_passthru_cmd admin_cmd = { 0 };
char correctable[8] = { 0 };
- int fd = -1;
FILE *fp;
char *res;
const char *desc = "Clear PCIe Device Correctable Errors";
@@ -1045,12 +1051,14 @@ static int micron_clear_pcie_correctable_errors(int argc, char **argv,
OPT_END()
};
- if ((fd = micron_parse_options(argc, argv, desc, opts, &model)) < 0)
+ err = micron_parse_options(&dev, argc, argv, desc, opts, &model);
+ if (err < 0)
return err;
/* For M51CX models, PCIe errors are cleared using 0xC3 feature */
if (model == M51CX) {
- err = nvme_set_features_simple(fd, fid, 0, (1 << 31), false, &result);
+ err = nvme_set_features_simple(dev_fd(dev), fid, 0, (1 << 31), false,
+ &result);
if (err == 0 && (err = (int)result) == 0) {
printf("Device correctable errors are cleared!\n");
goto out;
@@ -1059,7 +1067,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(fd, &admin_cmd, NULL);
+ err = nvme_submit_admin_passthru(dev_fd(dev), &admin_cmd, NULL);
if (err == 0) {
printf("Device correctable error counters are cleared!\n");
goto out;
@@ -1134,7 +1142,7 @@ static int micron_clear_pcie_correctable_errors(int argc, char **argv,
printf("Device correctable errors detected: %s\n", correctable);
err = 0;
out:
- close(fd);
+ dev_close(dev);
return err;
}
@@ -1490,7 +1498,8 @@ static int micron_nand_stats(int argc, char **argv,
unsigned int logFB[FB_log_size/sizeof(int)] = { 0 };
eDriveModel eModel = UNKNOWN_MODEL;
struct nvme_id_ctrl ctrl;
- int fd, err, ctrlIdx;
+ struct nvme_dev *dev;
+ int err, ctrlIdx;
__u8 nsze;
bool has_d0_log = true;
bool has_fb_log = false;
@@ -1508,8 +1517,8 @@ static int micron_nand_stats(int argc, char **argv,
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0) {
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err) {
printf("\nDevice not found \n");;
return -1;
}
@@ -1517,7 +1526,7 @@ static int micron_nand_stats(int argc, char **argv,
if (strcmp(cfg.fmt, "normal") == 0)
is_json = false;
- err = nvme_identify_ctrl(fd, &ctrl);
+ err = nvme_identify_ctrl(dev_fd(dev), &ctrl);
if (err) {
printf("Error %d retrieving controller identification data\n", err);
goto out;
@@ -1532,12 +1541,12 @@ static int micron_nand_stats(int argc, char **argv,
goto out;
}
- err = nvme_get_log_simple(fd, 0xD0, D0_log_size, extSmartLog);
+ err = nvme_get_log_simple(dev_fd(dev), 0xD0, D0_log_size, extSmartLog);
has_d0_log = (0 == err);
/* should check for firmware version if this log is supported or not */
if (eModel == M5407 || eModel == M5410) {
- err = nvme_get_log_simple(fd, 0xFB, FB_log_size, logFB);
+ err = nvme_get_log_simple(dev_fd(dev), 0xFB, FB_log_size, logFB);
has_fb_log = (0 == err);
}
@@ -1555,7 +1564,7 @@ static int micron_nand_stats(int argc, char **argv,
err = -ENOTTY;
}
out:
- close(fd);
+ dev_close(dev);
if (err > 0)
nvme_show_status(err);
@@ -1595,7 +1604,8 @@ static int micron_smart_ext_log(int argc, char **argv,
const char *desc = "Retrieve extended SMART logs for the given device ";
unsigned int extSmartLog[E1_log_size/sizeof(int)] = { 0 };
eDriveModel eModel = UNKNOWN_MODEL;
- int fd = 0, err = 0, ctrlIdx = 0;
+ int err = 0, ctrlIdx = 0;
+ struct nvme_dev *dev;
bool is_json = true;
struct format {
char *fmt;
@@ -1609,8 +1619,8 @@ static int micron_smart_ext_log(int argc, char **argv,
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0) {
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err) {
printf("\nDevice not found \n");;
return -1;
}
@@ -1623,13 +1633,13 @@ static int micron_smart_ext_log(int argc, char **argv,
err = -1;
goto out;
}
- err = nvme_get_log_simple(fd, 0xE1, E1_log_size, extSmartLog);
+ err = nvme_get_log_simple(dev_fd(dev), 0xE1, E1_log_size, extSmartLog);
if (!err) {
print_ext_smart_logs_e1((__u8 *)extSmartLog, is_json);
}
out:
- close(fd);
+ dev_close(dev);
if (err > 0)
nvme_show_status(err);
return err;
@@ -2005,7 +2015,6 @@ static int micron_drive_info(int argc, char **argv, struct command *cmd,
struct plugin *plugin)
{
const char *desc = "Get drive HW information";
- int fd, err = 0;
struct nvme_id_ctrl ctrl = { 0 };
struct nvme_passthru_cmd admin_cmd = { 0 };
struct fb_drive_info {
@@ -2018,9 +2027,11 @@ static int micron_drive_info(int argc, char **argv, struct command *cmd,
eDriveModel model = UNKNOWN_MODEL;
bool is_json = false;
struct json_object *root, *driveInfo;
+ struct nvme_dev *dev;
struct format {
char *fmt;
};
+ int err = 0;
const char *fmt = "output format normal";
struct format cfg = {
@@ -2032,12 +2043,13 @@ static int micron_drive_info(int argc, char **argv, struct command *cmd,
OPT_END()
};
- if ((fd = micron_parse_options(argc, argv, desc, opts, &model)) < 0)
+ err = micron_parse_options(&dev, argc, argv, desc, opts, &model);
+ if (err < 0)
return err;
if (model == UNKNOWN_MODEL) {
fprintf(stderr, "ERROR : Unsupported drive for vs-drive-info cmd");
- close(fd);
+ dev_close(dev);
return -1;
}
@@ -2049,17 +2061,17 @@ 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(fd, &admin_cmd, NULL);
+ err = nvme_submit_admin_passthru(dev_fd(dev), &admin_cmd, NULL);
if (err) {
fprintf(stderr, "ERROR : drive-info opcode failed with 0x%x\n", err);
- close(fd);
+ dev_close(dev);
return -1;
}
} else {
- err = nvme_identify_ctrl(fd, &ctrl);
+ err = nvme_identify_ctrl(dev_fd(dev), &ctrl);
if (err) {
fprintf(stderr, "ERROR : identify_ctrl() failed with 0x%x\n", err);
- close(fd);
+ dev_close(dev);
return -1;
}
dinfo.hw_ver_major = ctrl.vs[820];
@@ -2103,7 +2115,7 @@ static int micron_drive_info(int argc, char **argv, struct command *cmd,
}
}
- close(fd);
+ dev_close(dev);
return 0;
}
@@ -2242,10 +2254,11 @@ 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 };
eDriveModel eModel = UNKNOWN_MODEL;
- int fd, err;
+ struct nvme_dev *dev;
struct format {
char *fmt;
};
+ int err;
const char *fmt = "output format normal";
struct format cfg = {
@@ -2257,13 +2270,13 @@ static int micron_fw_activation_history(int argc, char **argv, struct command *c
OPT_END()
};
- if ((fd = micron_parse_options(argc, argv, desc, opts, &eModel)) < 0) {
+ err = micron_parse_options(&dev, argc, argv, desc, opts, &eModel);
+ if (err < 0)
return -1;
- }
if (strcmp(cfg.fmt, "normal") != 0) {
fprintf (stderr, "only normal format is supported currently\n");
- close(fd);
+ dev_close(dev);
return -1;
}
@@ -2274,7 +2287,7 @@ static int micron_fw_activation_history(int argc, char **argv, struct command *c
goto out;
}
- err = nvme_get_log_simple(fd, 0xC2, C2_log_size, logC2);
+ err = nvme_get_log_simple(dev_fd(dev), 0xC2, C2_log_size, logC2);
if (err) {
fprintf(stderr, "Failed to retrieve fw activation history log, error: %x\n", err);
goto out;
@@ -2308,7 +2321,7 @@ static int micron_fw_activation_history(int argc, char **argv, struct command *c
}
}
out:
- close(fd);
+ dev_close(dev);
return err;
}
@@ -2327,12 +2340,12 @@ static int micron_latency_stats_track(int argc, char **argv, struct command *cmd
const char *thrtime = "The threshold value to use for latency monitoring in"
" milliseconds, default is 800ms";
- int fd = 0;
int fid = MICRON_FID_LATENCY_MONITOR;
eDriveModel model = UNKNOWN_MODEL;
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;
struct {
char *option;
char *command;
@@ -2351,9 +2364,9 @@ static int micron_latency_stats_track(int argc, char **argv, struct command *cmd
};
- if ((fd = micron_parse_options(argc, argv, desc, opts, &model)) < 0) {
+ err = micron_parse_options(&dev, argc, argv, desc, opts, &model);
+ if (err < 0)
return -1;
- }
if (!strcmp(opt.option, "enable")) {
enable = 1;
@@ -2361,13 +2374,13 @@ 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);
- close(fd);
+ dev_close(dev);
return -1;
}
struct nvme_get_features_args g_args = {
.args_size = sizeof(g_args),
- .fd = fd,
+ .fd = dev_fd(dev),
.fid = fid,
.nsid = 0,
.sel = 0,
@@ -2382,7 +2395,7 @@ static int micron_latency_stats_track(int argc, char **argv, struct command *cmd
err = nvme_get_features(&g_args);
if (err != 0) {
printf("Failed to retrieve latency monitoring feature status\n");
- close(fd);
+ dev_close(dev);
return err;
}
@@ -2407,7 +2420,7 @@ static int micron_latency_stats_track(int argc, char **argv, struct command *cmd
} else if (result == 0) {
printf("\n");
}
- close(fd);
+ dev_close(dev);
return err;
}
@@ -2415,13 +2428,13 @@ 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");
- close(fd);
+ dev_close(dev);
return -1;
}
/* timing mask is in terms of 10ms units, so min allowed is 10ms */
else if ((opt.threshold % 10) != 0) {
printf("The threshold value should be multiple of 10 ms\n");
- close(fd);
+ dev_close(dev);
return -1;
}
opt.threshold /= 10;
@@ -2440,13 +2453,13 @@ 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);
- close(fd);
+ dev_close(dev);
return -1;
}
struct nvme_set_features_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.fid = MICRON_FID_LATENCY_MONITOR,
.nsid = 0,
.cdw11 = enable,
@@ -2469,7 +2482,7 @@ static int micron_latency_stats_track(int argc, char **argv, struct command *cmd
opt.option, opt.command, opt.threshold == 0 ? 800 : opt.threshold * 10);
}
- close(fd);
+ dev_close(dev);
return err;
}
@@ -2510,21 +2523,22 @@ static int micron_latency_stats_logs(int argc, char **argv, struct command *cmd,
uint32_t rfu[6];
} log[LATENCY_LOG_ENTRIES];
eDriveModel model = UNKNOWN_MODEL;
+ struct nvme_dev *dev;
int err = -1;
- int fd = -1;
const char *desc = "Display Latency tracking log information";
OPT_ARGS(opts) = {
OPT_END()
};
- if ((fd = micron_parse_options(argc, argv, desc, opts, &model)) < 0)
+ err = micron_parse_options(&dev, argc, argv, desc, opts, &model);
+ if (err)
return err;
memset(&log, 0, sizeof(log));
- err = nvme_get_log_simple(fd, 0xD1, sizeof(log), &log);
+ err = nvme_get_log_simple(dev_fd(dev), 0xD1, sizeof(log), &log);
if (err) {
if (err < 0)
printf("Unable to retrieve latency stats log the drive\n");
- close(fd);
+ dev_close(dev);
return err;
}
/* print header and each log entry */
@@ -2538,7 +2552,7 @@ static int micron_latency_stats_logs(int argc, char **argv, struct command *cmd,
log[i].deac, log[i].prinfo, log[i].fua, log[i].lr);
}
printf("\n");
- close(fd);
+ dev_close(dev);
return err;
}
@@ -2549,7 +2563,7 @@ static int micron_latency_stats_info(int argc, char **argv, struct command *cmd,
const char *command = "command to display stats - all|read|write|trim"
"default is all";
int err = 0;
- int fd = -1;
+ struct nvme_dev *dev;
eDriveModel model = UNKNOWN_MODEL;
#define LATENCY_BUCKET_COUNT 32
#define LATENCY_BUCKET_RSVD 32
@@ -2592,7 +2606,8 @@ static int micron_latency_stats_info(int argc, char **argv, struct command *cmd,
OPT_END()
};
- if ((fd = micron_parse_options(argc, argv, desc, opts, &model)) < 0)
+ err = micron_parse_options(&dev, argc, argv, desc, opts, &model);
+ if (err < 0)
return err;
if (!strcmp(opt.command, "read")) {
cmd_stats = &log.read_cmds[0];
@@ -2605,16 +2620,16 @@ 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);
- close(fd);
+ dev_close(dev);
return -1;
}
memset(&log, 0, sizeof(log));
- err = nvme_get_log_simple(fd, 0xD0, sizeof(log), &log);
+ err = nvme_get_log_simple(dev_fd(dev), 0xD0, sizeof(log), &log);
if (err) {
if (err < 0)
printf("Unable to retrieve latency stats log the drive\n");
- close(fd);
+ dev_close(dev);
return err;
}
printf("Micron IO %s Command Latency Statistics\n"
@@ -2636,7 +2651,7 @@ static int micron_latency_stats_info(int argc, char **argv, struct command *cmd,
printf("%2d %8s %8s %8"PRIu64"\n",
bucket, start, end, cmd_stats[b]);
}
- close(fd);
+ dev_close(dev);
return err;
}
@@ -2648,7 +2663,7 @@ 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;
eDriveModel eModel = UNKNOWN_MODEL;
- int fd, err = 0;
+ struct nvme_dev *dev;
bool is_json = true;
struct format {
char *fmt;
@@ -2657,15 +2672,16 @@ static int micron_ocp_smart_health_logs(int argc, char **argv, struct command *c
struct format cfg = {
.fmt = "json",
};
+ int err = 0;
OPT_ARGS(opts) = {
OPT_FMT("format", 'f', &cfg.fmt, fmt),
OPT_END()
};
- if ((fd = micron_parse_options(argc, argv, desc, opts, &eModel)) < 0) {
+ err = micron_parse_options(&dev, argc, argv, desc, opts, &eModel);
+ if (err < 0)
return -1;
- }
if (strcmp(cfg.fmt, "normal") == 0)
is_json = false;
@@ -2675,9 +2691,9 @@ static int micron_ocp_smart_health_logs(int argc, char **argv, struct command *c
__u8 spec = (eModel == M5410) ? 0 : 1;
__u8 nsze;
- if ((err = nvme_identify_ctrl(fd, &ctrl)) == 0)
- err = nvme_get_log_simple(fd, 0xFB,
- FB_log_size, logFB);
+ if ((err = nvme_identify_ctrl(dev_fd(dev), &ctrl)) == 0)
+ err = nvme_get_log_simple(dev_fd(dev), 0xFB,
+ FB_log_size, logFB);
if (err) {
if (err < 0)
printf("Unable to retrieve smart log 0xFB for the drive\n");
@@ -2698,14 +2714,14 @@ static int micron_ocp_smart_health_logs(int argc, char **argv, struct command *c
goto out;
}
- err = nvme_get_log_simple(fd, 0xC0, C0_log_size, logC0);
+ err = nvme_get_log_simple(dev_fd(dev), 0xC0, C0_log_size, logC0);
if (err == 0) {
print_smart_cloud_health_log((__u8 *)logC0, is_json);
} else if (err < 0) {
printf("Unable to retrieve extended smart log 0xC0 for the drive\n");
}
out:
- close(fd);
+ dev_close(dev);
if (err > 0)
nvme_show_status(err);
return err;
@@ -2715,28 +2731,30 @@ static int micron_clr_fw_activation_history(int argc, char **argv,
struct command *cmd, struct plugin *plugin)
{
const char *desc = "Clear FW activation history";
- int fd, err = 0;
__u32 result = 0;
__u8 fid = MICRON_FEATURE_CLEAR_FW_ACTIVATION_HISTORY;
eDriveModel model = UNKNOWN_MODEL;
+ struct nvme_dev *dev;
OPT_ARGS(opts) = {
OPT_END()
};
+ int err = 0;
- if ((fd = micron_parse_options(argc, argv, desc, opts, &model)) < 0)
+ err = micron_parse_options(&dev, argc, argv, desc, opts, &model);
+ if (err < 0)
return err;
if (model != M51CX) {
printf ("This option is not supported for specified drive\n");
- close(fd);
+ dev_close(dev);
return err;
}
- err = nvme_set_features_simple(fd, fid, 1 << 31, 0, 0, &result);
+ err = nvme_set_features_simple(dev_fd(dev), fid, 1 << 31, 0, 0, &result);
if (err == 0) err = (int)result;
else printf ("Failed to clear fw activation history, error = 0x%x\n", err);
- close(fd);
+ dev_close(dev);
return err;
}
@@ -2750,10 +2768,10 @@ static int micron_telemetry_cntrl_option(int argc, char **argv,
const char *select = "select/save values: enable/disable options"
"1 - save (persistent), 0 - non-persistent and for "
"status options: 0 - current, 1 - default, 2-saved";
- int fd = 0;
int fid = MICRON_FEATURE_TELEMETRY_CONTROL_OPTION;
eDriveModel model = UNKNOWN_MODEL;
struct nvme_id_ctrl ctrl = { 0 };
+ struct nvme_dev *dev;
struct {
char *option;
@@ -2769,21 +2787,21 @@ static int micron_telemetry_cntrl_option(int argc, char **argv,
OPT_END()
};
- if ((fd = micron_parse_options(argc, argv, desc, opts, &model)) < 0) {
+ err = micron_parse_options(&dev, argc, argv, desc, opts, &model);
+ if (err < 0)
return -1;
- }
- err = nvme_identify_ctrl(fd, &ctrl);
+ err = nvme_identify_ctrl(dev_fd(dev), &ctrl);
if ((ctrl.lpa & 0x8) != 0x8) {
printf("drive doesn't support host/controller generated telemetry logs\n");
- close(fd);
+ dev_close(dev);
return err;
}
if (!strcmp(opt.option, "enable")) {
struct nvme_set_features_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.fid = fid,
.nsid = 1,
.cdw11 = 1,
@@ -2805,7 +2823,7 @@ static int micron_telemetry_cntrl_option(int argc, char **argv,
} else if (!strcmp(opt.option, "disable")) {
struct nvme_set_features_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.fid = fid,
.nsid = 1,
.cdw11 = 0,
@@ -2827,7 +2845,7 @@ static int micron_telemetry_cntrl_option(int argc, char **argv,
} else if (!strcmp(opt.option, "status")) {
struct nvme_get_features_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.fid = fid,
.nsid = 1,
.sel = opt.select & 0x3,
@@ -2847,11 +2865,11 @@ 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);
- close(fd);
+ dev_close(dev);
return -1;
}
- close(fd);
+ dev_close(dev);
return err;
}
@@ -2945,7 +2963,7 @@ static int get_common_log(int fd, uint8_t id, uint8_t **buf, int *size)
if (hdr.log_size == sizeof(hdr)) {
buffer = (uint8_t *)malloc(sizeof(hdr));
if (buffer == NULL) {
- fprintf(stderr, "malloc of %lu bytes failed for log: 0x%X\n",
+ fprintf(stderr, "malloc of %zu bytes failed for log: 0x%X\n",
sizeof(hdr), id);
return -ENOMEM;
}
@@ -2953,7 +2971,7 @@ static int get_common_log(int fd, uint8_t id, uint8_t **buf, int *size)
} else if (hdr.log_size < hdr.max_size) {
buffer = (uint8_t *)malloc(sizeof(hdr) + hdr.log_size);
if (buffer == NULL) {
- fprintf(stderr, "malloc of %lu bytes failed for log: 0x%X\n",
+ fprintf(stderr, "malloc of %zu bytes failed for log: 0x%X\n",
hdr.log_size + sizeof(hdr), id);
return -ENOMEM;
}
@@ -2971,7 +2989,7 @@ static int get_common_log(int fd, uint8_t id, uint8_t **buf, int *size)
*/
buffer = (uint8_t *)malloc(hdr.max_size + sizeof(hdr));
if (buffer == NULL) {
- fprintf(stderr, "malloc of %lu bytes failed for log: 0x%X\n",
+ fprintf(stderr, "malloc of %zu bytes failed for log: 0x%X\n",
hdr.max_size + sizeof(hdr), id);
return -ENOMEM;
}
@@ -3010,7 +3028,6 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd,
struct plugin *plugin)
{
int err = -EINVAL;
- int fd = 0;
int ctrlIdx, telemetry_option = 0;
char strOSDirName[1024];
char strCtrlDirName[1024];
@@ -3021,6 +3038,7 @@ 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;
struct {
unsigned char ucLogPage;
const char *strFileName;
@@ -3104,10 +3122,9 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd,
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
-
- if (fd < 0)
- return fd;
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
/* if telemetry type is specified, check for data area */
if (strlen(cfg.type) != 0) {
@@ -3143,7 +3160,7 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd,
goto out;
}
- err = nvme_identify_ctrl(fd, &ctrl);
+ err = nvme_identify_ctrl(dev_fd(dev), &ctrl);
if (err)
goto out;
@@ -3151,11 +3168,12 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd,
if (telemetry_option) {
if ((ctrl.lpa & 0x8) != 0x8) {
printf("telemetry option is not supported for specified drive\n");
- close(fd);
+ dev_close(dev);
goto out;
}
int logSize = 0; __u8 *buffer = NULL; const char *dir = ".";
- err = micron_telemetry_log(fd, cfg.log, &buffer, &logSize, cfg.data_area);
+ err = micron_telemetry_log(dev_fd(dev), cfg.log, &buffer, &logSize,
+ cfg.data_area);
if (err == 0 && logSize > 0 && buffer != NULL) {
sprintf(msg, "telemetry log: 0x%X", cfg.log);
WriteData(buffer, logSize, dir, cfg.package, msg);
@@ -3184,16 +3202,16 @@ 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(fd, strCtrlDirName, i);
+ GetNSIDDInfo(dev_fd(dev), strCtrlDirName, i);
- GetSmartlogData(fd, strCtrlDirName);
- GetErrorlogData(fd, ctrl.elpe, strCtrlDirName);
- GetGenericLogs(fd, strCtrlDirName);
+ GetSmartlogData(dev_fd(dev), strCtrlDirName);
+ GetErrorlogData(dev_fd(dev), ctrl.elpe, strCtrlDirName);
+ GetGenericLogs(dev_fd(dev), strCtrlDirName);
/* pull if telemetry log data is supported */
if ((ctrl.lpa & 0x8) == 0x8)
- GetTelemetryData(fd, strCtrlDirName);
+ GetTelemetryData(dev_fd(dev), strCtrlDirName);
- GetFeatureSettings(fd, strCtrlDirName);
+ GetFeatureSettings(dev_fd(dev), strCtrlDirName);
if (eModel != M5410 && eModel != M5407) {
memcpy(&aVendorLogs[c_logs_index], aM51XXLogs, sizeof(aM51XXLogs));
@@ -3221,15 +3239,18 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd,
case 0xE4:
case 0xE8:
case 0xEA:
- err = get_common_log(fd, aVendorLogs[i].ucLogPage, &dataBuffer, &bSize);
+ err = get_common_log(dev_fd(dev), aVendorLogs[i].ucLogPage,
+ &dataBuffer, &bSize);
break;
case 0xC1:
case 0xC2:
case 0xC4:
- err = GetLogPageSize(fd, aVendorLogs[i].ucLogPage, &bSize);
+ err = GetLogPageSize(dev_fd(dev), aVendorLogs[i].ucLogPage,
+ &bSize);
if (err == 0 && bSize > 0)
- err = GetCommonLogPage(fd, aVendorLogs[i].ucLogPage, &dataBuffer, bSize);
+ err = GetCommonLogPage(dev_fd(dev), aVendorLogs[i].ucLogPage,
+ &dataBuffer, bSize);
break;
case 0xE6:
@@ -3248,9 +3269,12 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd,
if (bSize != 0 && (dataBuffer = (unsigned char *)malloc(bSize)) != NULL) {
memset(dataBuffer, 0, bSize);
if (eModel == M5410 || eModel == M5407)
- err = NVMEGetLogPage(fd, aVendorLogs[i].ucLogPage, dataBuffer, bSize);
+ err = NVMEGetLogPage(dev_fd(dev),
+ aVendorLogs[i].ucLogPage, dataBuffer,
+ bSize);
else
- err = nvme_get_log_simple(fd, aVendorLogs[i].ucLogPage,
+ err = nvme_get_log_simple(dev_fd(dev),
+ aVendorLogs[i].ucLogPage,
bSize, dataBuffer);
}
break;
@@ -3260,7 +3284,7 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd,
case 0xFC:
case 0xFD:
if (eModel == M51BX) {
- (void)NVMEResetLog(fd, aVendorLogs[i].ucLogPage,
+ (void)NVMEResetLog(dev_fd(dev), aVendorLogs[i].ucLogPage,
aVendorLogs[i].nLogSize, aVendorLogs[i].nMaxSize);
}
/* fallthrough */
@@ -3271,13 +3295,14 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd,
break;
}
memset(dataBuffer, 0, bSize);
- err = nvme_get_log_simple(fd, aVendorLogs[i].ucLogPage,
+ err = nvme_get_log_simple(dev_fd(dev), aVendorLogs[i].ucLogPage,
bSize, dataBuffer);
maxSize = aVendorLogs[i].nMaxSize - bSize;
while (err == 0 && 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(fd, aVendorLogs[i].ucLogPage,
+ err = nvme_get_log_simple(dev_fd(dev),
+ aVendorLogs[i].ucLogPage,
bSize, dataBuffer);
if (err || (((unsigned int *)dataBuffer)[0] == 0xdeadbeef))
break;
@@ -3299,7 +3324,7 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd,
err = ZipAndRemoveDir(strMainDirName, cfg.package);
out:
- close(fd);
+ dev_close(dev);
return err;
}
@@ -3308,17 +3333,18 @@ static int micron_logpage_dir(int argc, char **argv, struct command *cmd,
struct plugin *plugin)
{
int err = -1;
- int fd = -1;
const char *desc = "List the supported log pages";
eDriveModel model = UNKNOWN_MODEL;
char logbuf[MIN_LOG_SIZE];
+ struct nvme_dev *dev;
int i;
OPT_ARGS(opts) = {
OPT_END()
};
- if ((fd = micron_parse_options(argc, argv, desc, opts, &model)) < 0)
+ err = micron_parse_options(&dev, argc, argv, desc, opts, &model);
+ if (err < 0)
return err;
struct nvme_supported_logs {
@@ -3359,7 +3385,7 @@ 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 < sizeof(log_list)/sizeof(log_list[0]); i++) {
- err = nvme_get_log_simple(fd, log_list[i].log_id,
+ err = nvme_get_log_simple(dev_fd(dev), log_list[i].log_id,
MIN_LOG_SIZE, &logbuf[0]);
if (err) continue;
printf("%02Xh : %s\n", log_list[i].log_id, log_list[i].desc);
diff --git a/plugins/netapp/netapp-nvme.c b/plugins/netapp/netapp-nvme.c
index b6bd3f6..f5cb073 100644
--- a/plugins/netapp/netapp-nvme.c
+++ b/plugins/netapp/netapp-nvme.c
@@ -22,7 +22,6 @@
#include <unistd.h>
#include <errno.h>
#include <string.h>
-#include <uuid/uuid.h>
#include "common.h"
#include "nvme.h"
@@ -68,7 +67,7 @@ struct ontapdevice_info {
unsigned nsid;
struct nvme_id_ctrl ctrl;
struct nvme_id_ns ns;
- uuid_t uuid;
+ unsigned char uuid[NVME_UUID_LEN];
unsigned char log_data[ONTAP_C2_LOG_SIZE];
char dev[265];
};
@@ -334,7 +333,7 @@ static void netapp_ontapdevices_print(struct ontapdevice_info *devices,
for (i = 0; i < count; i++) {
netapp_get_ns_size(size, &lba, &devices[i].ns);
- uuid_unparse_lower(devices[i].uuid, uuid_str);
+ nvme_uuid_to_string(devices[i].uuid, uuid_str);
netapp_get_ontap_labels(vsname, nspath, devices[i].log_data);
if (format == NJSON) {
diff --git a/plugins/ocp/ocp-nvme.c b/plugins/ocp/ocp-nvme.c
index 52c28a8..5cbf6cb 100644
--- a/plugins/ocp/ocp-nvme.c
+++ b/plugins/ocp/ocp-nvme.c
@@ -13,12 +13,14 @@
#include <limits.h>
#include <fcntl.h>
#include <unistd.h>
+#include <time.h>
#include "common.h"
#include "nvme.h"
#include "libnvme.h"
#include "plugin.h"
#include "linux/types.h"
+#include "util/types.h"
#include "nvme-print.h"
#define CREATE_CMD
@@ -122,18 +124,6 @@ struct __attribute__((__packed__)) ssd_latency_monitor_log {
__u8 log_page_guid[0x10]; /* 0x1F0 */
};
-static long double int128_to_double(__u8 *data)
-{
- int i;
- long double result = 0;
-
- for (i = 0; i < 16; i++) {
- result *= 256;
- result += data[15 - i];
- }
- return result;
-}
-
static int convert_ts(time_t time, char *ts_buf)
{
struct tm gmTimeInfo;
@@ -208,10 +198,10 @@ static void ocp_print_C0_log_normal(void *data)
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_SVN]));
printf(" NUSE - Namespace utilization %"PRIu64"\n",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_NUSE]));
- printf(" PLP start count %.0Lf\n",
- int128_to_double(&log_data[SCAO_PSC]));
- printf(" Endurance estimate %.0Lf\n",
- int128_to_double(&log_data[SCAO_EEST]));
+ printf(" PLP start count %s\n",
+ uint128_t_to_string(le128_to_cpu(&log_data[SCAO_PSC])));
+ printf(" Endurance estimate %s\n",
+ uint128_t_to_string(le128_to_cpu(&log_data[SCAO_EEST])));
smart_log_ver = (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_LPV]);
printf(" Log page version %"PRIu16"\n",smart_log_ver);
printf(" Log page GUID 0x");
@@ -300,10 +290,10 @@ static void ocp_print_C0_log_json(void *data)
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_SVN]));
json_object_add_value_uint64(root, "NUSE - Namespace utilization",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_NUSE]));
- json_object_add_value_uint(root, "PLP start count",
- int128_to_double(&log_data[SCAO_PSC]));
- json_object_add_value_uint64(root, "Endurance estimate",
- int128_to_double(&log_data[SCAO_EEST]));
+ json_object_add_value_uint128(root, "PLP start count",
+ le128_to_cpu(&log_data[SCAO_PSC]));
+ json_object_add_value_uint128(root, "Endurance estimate",
+ le128_to_cpu(&log_data[SCAO_EEST]));
smart_log_ver = (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_LPV]);
json_object_add_value_uint(root, "Log page version", smart_log_ver);
char guid[40];
@@ -401,7 +391,7 @@ static int ocp_smart_add_log(int argc, char **argv, struct command *cmd,
struct plugin *plugin)
{
const char *desc = "Retrieve latency monitor log data.";
- int fd;
+ struct nvme_dev *dev;
int ret = 0;
struct config {
@@ -417,22 +407,23 @@ static int ocp_smart_add_log(int argc, char **argv, struct command *cmd,
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
+ if (ret)
+ return ret;
- ret = get_c0_log_page(fd, cfg.output_format);
+ ret = get_c0_log_page(dev_fd(dev), cfg.output_format);
if (ret)
fprintf(stderr, "ERROR : OCP : Failure reading the C0 Log Page, ret = %d\n",
ret);
- close(fd);
+ dev_close(dev);
return ret;
}
-static int ocp_print_C3_log_normal(struct ssd_latency_monitor_log *log_data)
+static int ocp_print_C3_log_normal(struct nvme_dev *dev,
+ struct ssd_latency_monitor_log *log_data)
{
printf("-Latency Monitor/C3 Log Page Data- \n");
- printf(" Controller : %s\n", devicename);
+ printf(" Controller : %s\n", dev->name);
int i, j;
int pos = 0;
char ts_buf[128];
@@ -662,7 +653,7 @@ static void ocp_print_C3_log_json(struct ssd_latency_monitor_log *log_data)
json_free_object(root);
}
-static int get_c3_log_page(int fd, char *format)
+static int get_c3_log_page(struct nvme_dev *dev, char *format)
{
int ret = 0;
int fmt = -1;
@@ -682,8 +673,8 @@ static int get_c3_log_page(int fd, char *format)
}
memset(data, 0, sizeof (__u8) * C3_LATENCY_MON_LOG_BUF_LEN);
- ret = nvme_get_log_simple(fd, C3_LATENCY_MON_OPCODE,
- C3_LATENCY_MON_LOG_BUF_LEN, data);
+ ret = nvme_get_log_simple(dev_fd(dev), C3_LATENCY_MON_OPCODE,
+ C3_LATENCY_MON_LOG_BUF_LEN, data);
if (strcmp(format, "json"))
fprintf(stderr,
@@ -725,7 +716,7 @@ static int get_c3_log_page(int fd, char *format)
switch (fmt) {
case NORMAL:
- ocp_print_C3_log_normal(log_data);
+ ocp_print_C3_log_normal(dev, log_data);
break;
case JSON:
ocp_print_C3_log_json(log_data);
@@ -745,7 +736,7 @@ static int ocp_latency_monitor_log(int argc, char **argv, struct command *comman
struct plugin *plugin)
{
const char *desc = "Retrieve latency monitor log data.";
- int fd;
+ struct nvme_dev *dev;
int ret = 0;
struct config {
@@ -762,15 +753,15 @@ static int ocp_latency_monitor_log(int argc, char **argv, struct command *comman
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
+ if (ret)
+ return ret;
- ret = get_c3_log_page(fd, cfg.output_format);
+ ret = get_c3_log_page(dev, cfg.output_format);
if (ret)
fprintf(stderr,
"ERROR : OCP : Failure reading the C3 Log Page, ret = %d\n",
ret);
- close(fd);
+ dev_close(dev);
return ret;
}
diff --git a/plugins/scaleflux/sfx-nvme.c b/plugins/scaleflux/sfx-nvme.c
index 0740e43..a776664 100644
--- a/plugins/scaleflux/sfx-nvme.c
+++ b/plugins/scaleflux/sfx-nvme.c
@@ -398,17 +398,18 @@ 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)
{
struct nvme_additional_smart_log smart_log;
- int err, fd;
char *desc = "Get ScaleFlux 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";
const char *json= "Dump output in json format";
+ struct nvme_dev *dev;
struct config {
__u32 namespace_id;
bool raw_binary;
bool json;
};
+ int err;
struct config cfg = {
.namespace_id = 0xffffffff,
@@ -422,24 +423,25 @@ static int get_additional_smart_log(int argc, char **argv, struct command *cmd,
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0) {
- return fd;
- }
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
- err = nvme_get_nsid_log(fd, false, 0xca, cfg.namespace_id,
- sizeof(smart_log), (void *)&smart_log);
+ err = nvme_get_nsid_log(dev_fd(dev), false, 0xca, cfg.namespace_id,
+ sizeof(smart_log), (void *)&smart_log);
if (!err) {
if (cfg.json)
- show_sfx_smart_log_jsn(&smart_log, cfg.namespace_id, devicename);
+ show_sfx_smart_log_jsn(&smart_log, cfg.namespace_id,
+ dev->name);
else if (!cfg.raw_binary)
- show_sfx_smart_log(&smart_log, cfg.namespace_id, devicename);
+ show_sfx_smart_log(&smart_log, cfg.namespace_id,
+ dev->name);
else
d_raw((unsigned char *)&smart_log, sizeof(smart_log));
}
else if (err > 0)
nvme_show_status(err);
- close(fd);
+ dev_close(dev);
return err;
}
@@ -609,22 +611,23 @@ static void show_lat_stats_myrtle(struct sfx_lat_stats_myrtle *stats, int write)
for (i = 0; i < 64; i++)
printf("Bucket %2d: %u\n", i, stats->bucket_19[i]);
- printf("\nAverage latency statistics %lld\n", stats->average);
+ printf("\nAverage latency statistics %" PRIu64 "\n",
+ (uint64_t)stats->average);
}
static int get_lat_stats_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
struct sfx_lat_stats stats;
- int err, fd;
-
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;
struct config {
bool raw_binary;
bool write;
};
+ int err;
struct config cfg = {
};
@@ -635,12 +638,12 @@ static int get_lat_stats_log(int argc, char **argv, struct command *cmd, struct
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0) {
- return fd;
- }
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
- err = nvme_get_log_simple(fd, cfg.write ? 0xc3 : 0xc1, sizeof(stats), (void *)&stats);
+ err = nvme_get_log_simple(dev_fd(dev), cfg.write ? 0xc3 : 0xc1,
+ sizeof(stats), (void *)&stats);
if (!err) {
if ((stats.ver.maj == VANDA_MAJOR_IDX) && (stats.ver.min == VANDA_MINOR_IDX)) {
if (!cfg.raw_binary) {
@@ -660,7 +663,7 @@ static int get_lat_stats_log(int argc, char **argv, struct command *cmd, struct
}
} else if (err > 0)
nvme_show_status(err);
- close(fd);
+ dev_close(dev);
return err;
}
@@ -764,9 +767,9 @@ static void bd_table_show(unsigned char *bd_table, __u64 table_size)
*/
static int sfx_get_bad_block(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- int fd;
- unsigned char *data_buf;
const __u64 buf_size = 256*4096*sizeof(unsigned char);
+ unsigned char *data_buf;
+ struct nvme_dev *dev;
int err = 0;
char *desc = "Get bad block table of sfx block device.";
@@ -775,19 +778,18 @@ static int sfx_get_bad_block(int argc, char **argv, struct command *cmd, struct
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0) {
- return fd;
- }
+ err = parse_and_open(&dev, 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);
- close(fd);
+ dev_close(dev);
return -1;
}
- err = get_bb_table(fd, 0xffffffff, data_buf, buf_size);
+ err = get_bb_table(dev_fd(dev), 0xffffffff, data_buf, buf_size);
if (err < 0) {
perror("get-bad-block");
} else if (err != 0) {
@@ -798,7 +800,7 @@ static int sfx_get_bad_block(int argc, char **argv, struct command *cmd, struct
}
free(data_buf);
- close(fd);
+ dev_close(dev);
return 0;
}
@@ -819,25 +821,25 @@ static void show_cap_info(struct sfx_freespace_ctx *ctx)
static int query_cap_info(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
struct sfx_freespace_ctx ctx = { 0 };
- int err = 0, fd;
char *desc = "query current capacity info";
const char *raw = "dump output in binary format";
+ struct nvme_dev *dev;
struct config {
bool raw_binary;
};
struct config cfg;
+ int err = 0;
OPT_ARGS(opts) = {
OPT_FLAG("raw-binary", 'b', &cfg.raw_binary, raw),
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0) {
- return fd;
- }
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
- if (nvme_query_cap(fd, 0xffffffff, sizeof(ctx), &ctx)) {
+ if (nvme_query_cap(dev_fd(dev), 0xffffffff, sizeof(ctx), &ctx)) {
perror("sfx-query-cap");
err = -1;
}
@@ -849,7 +851,7 @@ static int query_cap_info(int argc, char **argv, struct command *cmd, struct plu
d_raw((unsigned char *)&ctx, sizeof(ctx));
}
}
- close(fd);
+ dev_close(dev);
return err;
}
@@ -939,14 +941,15 @@ static int sfx_confirm_change(const char *str)
static int change_cap(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- int err = -1, fd;
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;
__u64 cap_in_4k = 0;
__u64 cap_in_sec = 0;
int shrink = 0;
+ int err = -1;
struct config {
__u64 cap_in_byte;
@@ -967,10 +970,9 @@ static int change_cap(int argc, char **argv, struct command *cmd, struct plugin
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0) {
- return fd;
- }
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
cap_in_sec = IDEMA_CAP(cfg.capacity_in_gb);
cap_in_4k = cap_in_sec >> 3;
@@ -979,27 +981,27 @@ 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(fd, cap_in_4k, &shrink)) {
+ if (change_sanity_check(dev_fd(dev), cap_in_4k, &shrink)) {
printf("ScaleFlux change-capacity: fail\n");
- close(fd);
+ dev_close(dev);
return err;
}
if (!cfg.force && shrink && !sfx_confirm_change("Changing Cap may irrevocably delete this device's data")) {
- close(fd);
+ dev_close(dev);
return 0;
}
- err = nvme_change_cap(fd, 0xffffffff, cap_in_4k);
+ err = nvme_change_cap(dev_fd(dev), 0xffffffff, cap_in_4k);
if (err < 0)
perror("sfx-change-cap");
else if (err != 0)
nvme_show_status(err);
else {
printf("ScaleFlux change-capacity: success\n");
- ioctl(fd, BLKRRPART);
+ ioctl(dev_fd(dev), BLKRRPART);
}
- close(fd);
+ dev_close(dev);
return err;
}
@@ -1051,7 +1053,6 @@ char *sfx_feature_to_string(int feature)
static int sfx_set_feature(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- int err = 0, fd;
char *desc = "ScaleFlux internal set features\n"
"feature id 1: ATOMIC\n"
"value 0: Disable atomic write\n"
@@ -1060,8 +1061,9 @@ 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;
struct nvme_id_ns ns;
+ int err = 0;
struct config {
__u32 namespace_id;
@@ -1084,37 +1086,37 @@ static int sfx_set_feature(int argc, char **argv, struct command *cmd, struct pl
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0) {
- return fd;
- }
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
if (!cfg.feature_id) {
fprintf(stderr, "feature-id required param\n");
- close(fd);
+ dev_close(dev);
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")) {
- close(fd);
+ dev_close(dev);
return 0;
} else {
- return sfx_clean_card(fd);
+ return sfx_clean_card(dev_fd(dev));
}
}
if (cfg.feature_id == SFX_FEAT_ATOMIC && cfg.value != 0) {
if (cfg.namespace_id != 0xffffffff) {
- err = nvme_identify_ns(fd, cfg.namespace_id, &ns);
+ err = nvme_identify_ns(dev_fd(dev), cfg.namespace_id,
+ &ns);
if (err) {
if (err < 0)
perror("identify-namespace");
else
nvme_show_status(err);
- close(fd);
+ dev_close(dev);
return err;
}
/*
@@ -1122,29 +1124,31 @@ static int sfx_set_feature(int argc, char **argv, struct command *cmd, struct pl
*/
if ((ns.flbas & 0xf) != 1) {
printf("Please change-sector size to 4K, then retry\n");
- close(fd);
+ dev_close(dev);
return EFAULT;
}
}
} else if (cfg.feature_id == SFX_FEAT_UP_P_CAP) {
if (cfg.value <= 0) {
fprintf(stderr, "Invalid Param\n");
- close(fd);
+ dev_close(dev);
return EINVAL;
}
/*Warning for change pacp by GB*/
if (!cfg.force && !sfx_confirm_change("Changing physical capacity may irrevocably delete this device's data")) {
- close(fd);
+ dev_close(dev);
return 0;
}
}
- err = nvme_sfx_set_features(fd, cfg.namespace_id, cfg.feature_id, cfg.value);
+ err = nvme_sfx_set_features(dev_fd(dev), cfg.namespace_id,
+ cfg.feature_id,
+ cfg.value);
if (err < 0) {
perror("ScaleFlux-set-feature");
- close(fd);
+ dev_close(dev);
return errno;
} else if (!err) {
printf("ScaleFlux set-feature:%#02x (%s), value:%d\n", cfg.feature_id,
@@ -1152,18 +1156,19 @@ static int sfx_set_feature(int argc, char **argv, struct command *cmd, struct pl
} else if (err > 0)
nvme_show_status(err);
- close(fd);
+ dev_close(dev);
return err;
}
static int sfx_get_feature(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- int err = 0, fd;
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;
__u32 result = 0;
+ int err = 0;
struct config {
__u32 namespace_id;
@@ -1180,21 +1185,21 @@ static int sfx_get_feature(int argc, char **argv, struct command *cmd, struct pl
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0) {
- return fd;
- }
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
if (!cfg.feature_id) {
fprintf(stderr, "feature-id required param\n");
- close(fd);
+ dev_close(dev);
return EINVAL;
}
- err = nvme_sfx_get_features(fd, cfg.namespace_id, cfg.feature_id, &result);
+ err = nvme_sfx_get_features(dev_fd(dev), cfg.namespace_id,
+ cfg.feature_id, &result);
if (err < 0) {
perror("ScaleFlux-get-feature");
- close(fd);
+ dev_close(dev);
return errno;
} else if (!err) {
printf("ScaleFlux get-feature:%02x (%s), value:%d\n", cfg.feature_id,
@@ -1202,7 +1207,7 @@ static int sfx_get_feature(int argc, char **argv, struct command *cmd, struct pl
} else if (err > 0)
nvme_show_status(err);
- close(fd);
+ dev_close(dev);
return err;
}
diff --git a/plugins/seagate/seagate-diag.h b/plugins/seagate/seagate-diag.h
index 139901d..39f0d39 100644
--- a/plugins/seagate/seagate-diag.h
+++ b/plugins/seagate/seagate-diag.h
@@ -18,6 +18,8 @@
*
* \file seagate-diag.h
* \brief This file defines the functions and macros to make building a nvme-cli seagate plug-in.
+ *
+ * Author: Debabrata Bardhan <debabrata.bardhan@seagate.com>
*/
@@ -25,19 +27,66 @@
#define SEAGATE_NVME_H
#define SEAGATE_PLUGIN_VERSION_MAJOR 1
-#define SEAGATE_PLUGIN_VERSION_MINOR 1
+#define SEAGATE_PLUGIN_VERSION_MINOR 2
+
+#define SEAGATE_OCP_PLUGIN_VERSION_MAJOR 1
+#define SEAGATE_OCP_PLUGIN_VERSION_MINOR 0
#define PERSIST_FILE_SIZE (2764800)
#define ONE_MB (1048576) /* (1024 * 1024) */
#define PERSIST_CHUNK (65536) /* (1024 * 64) */
#define FOUR_KB (4096)
+#define STX_NUM_LEGACY_DRV (123)
+
+
+const char* stx_jag_pan_mn[STX_NUM_LEGACY_DRV] = {"ST1000KN0002", "ST1000KN0012", "ST2000KN0002",
+ "ST2000KN0012", "ST4000KN0002", "XP1600HE10002",
+ "XP1600HE10012", "XP1600HE30002", "XP1600HE30012",
+ "XP1920LE10002", "XP1920LE10012", "XP1920LE30002",
+ "XP1920LE30012", "XP3200HE10002", "XP3200HE10012",
+ "XP3840LE10002", "XP3840LE10012", "XP400HE30002",
+ "XP400HE30012", "XP400HE30022", "XP400HE30032",
+ "XP480LE30002", "XP480LE30012", "XP480LE30022",
+ "XP480LE30032", "XP800HE10002", "XP800HE10012",
+ "XP800HE30002", "XP800HE30012", "XP800HE30022",
+ "XP800HE30032", "XP960LE10002", "XP960LE10012",
+ "XP960LE30002", "XP960LE30012", "XP960LE30022",
+ "XP960LE30032", "XP256LE30011", "XP256LE30021",
+ "XP7680LE80002", "XP7680LE80003", "XP15360LE80003",
+ "XP30720LE80003", "XP7200-1A2048", "XP7200-1A4096",
+ "XP7201-2A2048", "XP7201-2A4096", "XP7200-1A8192",
+ "ST1000HM0021", "ST1000HM0031", "ST1000HM0061",
+ "ST1000HM0071", "ST1000HM0081", "ST1200HM0001",
+ "ST1600HM0031", "ST1800HM0001", "ST1800HM0011",
+ "ST2000HM0011", "ST2000HM0031", "ST400HM0061",
+ "ST400HM0071", "ST500HM0021", "ST500HM0031",
+ "ST500HM0061", "ST500HM0071", "ST500HM0081",
+ "ST800HM0061", "ST800HM0071", "ST1600HM0011",
+ "ST1600KN0001", "ST1600KN0011", "ST1920HM0001",
+ "ST1920KN0001", "ST1920KN0011", "ST400HM0021",
+ "ST400KN0001", "ST400KN0011", "ST480HM0001",
+ "ST480KN0001", "ST480KN0011", "ST800HM0021",
+ "ST800KN0001", "ST800KN0011", "ST960HM0001",
+ "ST960KN0001", "ST960KN0011", "XF1441-1AA251024",
+ "XF1441-1AA252048", "XF1441-1AA25512", "XF1441-1AB251024",
+ "XF1441-1AB252048", "XF1441-1AB25512", "XF1441-1BA251024",
+ "XF1441-1BA252048", "XF1441-1BA25512", "XF1441-1BB251024",
+ "XF1441-1BB252048", "XF1441-1BB25512", "ST400HM0031",
+ "ST400KN0021", "ST400KN0031", "ST480HM0011",
+ "ST480KN0021", "ST480KN0031", "ST800HM0031",
+ "ST800KN0021", "ST800KN0031", "ST960HM0011",
+ "ST960KN0021", "ST960KN0031", "XM1441-1AA111024",
+ "XM1441-1AA112048", "XM1441-1AA11512", "XM1441-1AA801024",
+ "XM1441-1AA80512", "XM1441-1AB111024", "XM1441-1AB112048",
+ "XM1441-1BA111024", "XM1441-1BA112048", "XM1441-1BA11512",
+ "XM1441-1BA801024", "XM1441-1BA80512", "XM1441-1BB112048"};
/***************************
*Supported Log-Pages from FW
***************************/
-typedef struct log_page_map_entry {
+typedef struct __attribute__((__packed__)) log_page_map_entry {
__u32 LogPageID;
__u32 LogPageSignature;
__u32 LogPageVersion;
@@ -45,7 +94,7 @@ typedef struct log_page_map_entry {
#define MAX_SUPPORTED_LOG_PAGE_ENTRIES ((4096 - sizeof(__u32)) / sizeof(log_page_map_entry))
-typedef struct log_page_map {
+typedef struct __attribute__((__packed__)) log_page_map {
__u32 NumLogPages;
log_page_map_entry LogPageEntry[ MAX_SUPPORTED_LOG_PAGE_ENTRIES ];
} log_page_map;
@@ -55,7 +104,6 @@ typedef struct log_page_map {
/***************************
* Extended-SMART Information
***************************/
-#pragma pack(1)
#define NUMBER_EXTENDED_SMART_ATTRIBUTES 42
typedef enum _EXTENDED_SMART_VERSION_
@@ -65,7 +113,7 @@ typedef enum _EXTENDED_SMART_VERSION_
EXTENDED_SMART_VERSION_VENDOR1,
} EXTENDED_SMART_VERSION;
-typedef struct _SmartVendorSpecific
+typedef struct __attribute__((__packed__)) _SmartVendorSpecific
{
__u8 AttributeNumber;
__u16 SmartStatus;
@@ -75,22 +123,22 @@ typedef struct _SmartVendorSpecific
__u8 RawHigh[3];
} SmartVendorSpecific;
-typedef struct _EXTENDED_SMART_INFO_T
+typedef struct __attribute__((__packed__)) _EXTENDED_SMART_INFO_T
{
__u16 Version;
SmartVendorSpecific vendorData[NUMBER_EXTENDED_SMART_ATTRIBUTES];
__u8 vendor_specific_reserved[6];
} EXTENDED_SMART_INFO_T;
-typedef struct vendor_smart_attribute_data
+typedef struct __attribute__((__packed__)) vendor_smart_attribute_data
{
- __u8 AttributeNumber; /* 00 */
- __u8 Rsvd[3]; /* 01 -03 */
- __u32 LSDword; /* 04-07 */
- __u32 MSDword; /* 08 - 11 */
+ __u8 AttributeNumber;
+ __u8 Rsvd[3];
+ __u32 LSDword;
+ __u32 MSDword;
} vendor_smart_attribute_data;
-struct nvme_temetry_log_hdr
+struct __attribute__((__packed__)) nvme_temetry_log_hdr
{
__u8 log_id;
__u8 rsvd1[4];
@@ -104,38 +152,75 @@ struct nvme_temetry_log_hdr
__u8 reason_identifier[128];
};
-typedef struct _U128
+typedef struct __attribute__((__packed__)) _U128
{
__u64 LS__u64;
__u64 MS__u64;
} U128;
-typedef struct _vendor_log_page_CF_Attr
+typedef struct __attribute__((__packed__)) _vendor_log_page_CF_Attr
{
- __u16 SuperCapCurrentTemperature; /* 00-01 */
- __u16 SuperCapMaximumTemperature; /* 02-03 */
- __u8 SuperCapStatus; /* 04 */
- __u8 Reserved5to7[3]; /* 05-07 */
- U128 DataUnitsReadToDramNamespace; /* 08-23 */
- U128 DataUnitsWrittenToDramNamespace; /* 24-39 */
- __u64 DramCorrectableErrorCount; /* 40-47 */
- __u64 DramUncorrectableErrorCount; /* 48-55 */
-}vendor_log_page_CF_Attr;
-
-typedef struct _vendor_log_page_CF
+ __u16 SuperCapCurrentTemperature;
+ __u16 SuperCapMaximumTemperature;
+ __u8 SuperCapStatus;
+ __u8 Reserved5to7[3];
+ U128 DataUnitsReadToDramNamespace;
+ U128 DataUnitsWrittenToDramNamespace;
+ __u64 DramCorrectableErrorCount;
+ __u64 DramUncorrectableErrorCount;
+} vendor_log_page_CF_Attr;
+
+typedef struct __attribute__((__packed__)) _vendor_log_page_CF
{
vendor_log_page_CF_Attr AttrCF;
__u8 Vendor_Specific_Reserved[ 456 ]; /* 56-511 */
-}vendor_log_page_CF;
+} vendor_log_page_CF;
+
+typedef struct __attribute__((__packed__)) _STX_EXT_SMART_LOG_PAGE_C0
+{
+ U128 phyMediaUnitsWrt;
+ U128 phyMediaUnitsRd;
+ __u64 badUsrNandBlocks;
+ __u64 badSysNandBlocks;
+ __u64 xorRecoveryCnt;
+ __u64 ucRdEc;
+ __u64 softEccEc;
+ __u64 etoeCrrCnt;
+ __u64 sysDataUsed : 8;
+ __u64 refreshCount : 56;
+ __u64 usrDataEraseCnt;
+ __u16 thermalThrottling;
+ __u8 dssdSpecVerErrata;
+ __u16 dssdSpecVerPoint;
+ __u16 dssdSpecVerMinor;
+ __u8 dssdSpecVerMajor;
+ __u64 pcieCorrEc;
+ __u32 incompleteShutdowns;
+ __u32 rsvd_116_119;
+ __u8 freeBlocks;
+ __u8 rsvd_121_127[7];
+ __u16 capHealth;
+ __u8 nvmeErrataVer;
+ __u8 rsvd_131_135[5];
+ __u64 unalignedIO;
+ __u64 secVerNum;
+ __u64 totalNUSE;
+ U128 plpStartCnt;
+ U128 enduranceEstimate;
+ __u64 pcieLinkRetCnt;
+ __u64 powStateChangeCnt;
+ __u8 rsvd_208_493[286];
+ __u16 logPageVer;
+ U128 logPageGUID;
+} STX_EXT_SMART_LOG_PAGE_C0;
-#pragma pack()
/* EOF Extended-SMART Information*/
/**************************
* PCIE ERROR INFORMATION
**************************/
-typedef struct pcie_error_log_page
+typedef struct __attribute__((__packed__)) pcie_error_log_page
{
__u32 Version;
__u32 BadDllpErrCnt;
@@ -159,53 +244,86 @@ typedef struct pcie_error_log_page
} pcie_error_log_page;
/*EOF PCIE ERROR INFORMATION */
+/**************************************
+* FW Activation History Log INFORMATION
+***************************************/
+
+typedef struct __attribute__((__packed__)) _stx_fw_activ_his_ele
+{
+ __u8 entryVerNum;
+ __u8 entryLen;
+ __u16 rev02_03;
+ __u16 fwActivCnt;
+ __u64 timeStamp;
+ __u64 rev14_21;
+ __u64 powCycleCnt;
+ __u8 previousFW[8];
+ __u8 newFW[8];
+ __u8 slotNum;
+ __u8 commitActionType;
+ __u16 result;
+ __u8 rev50_63[14];
+} stx_fw_activ_his_ele;
+
+typedef struct __attribute__((__packed__)) _stx_fw_activ_history_log_page
+{
+ __u8 logID;
+ __u8 rev01_03[3];
+ __u32 numValidFwActHisEnt;
+ stx_fw_activ_his_ele fwActHisEnt[20];
+ __u8 rev1288_4077[2790];
+ __u16 logPageVer;
+ __u8 logPageGUID[16];
+} stx_fw_activ_history_log_page;
+
+/* FW Activation History Log INFORMATION */
+
+
typedef enum
{
- VS_ATTR_SOFT_READ_ERROR_RATE, /* 0 OFFSET : 02 -13 bytes */
- VS_ATTR_REALLOCATED_SECTOR_COUNT, /* 1 OFFSET : 14 -25 bytes */
- VS_ATTR_POWER_ON_HOURS, /* 2 OFFSET : 26 -37 bytes */
+ VS_ATTR_SOFT_READ_ERROR_RATE, /* 0 OFFSET : 02 -13 bytes */
+ VS_ATTR_REALLOCATED_SECTOR_COUNT, /* 1 OFFSET : 14 -25 bytes */
+ VS_ATTR_POWER_ON_HOURS, /* 2 OFFSET : 26 -37 bytes */
VS_ATTR_POWER_FAIL_EVENT_COUNT, /* 3 OFFSET : 38 -49 bytes */
VS_ATTR_DEVICE_POWER_CYCLE_COUNT, /* 4 OFFSET : 50 -61 bytes */
- VS_ATTR_GB_ERASED, /* 5 OFFSET : 62 -73 bytes */
+ VS_ATTR_GB_ERASED, /* 5 OFFSET : 62 -73 bytes */
VS_ATTR_LIFETIME_DEVSLEEP_EXIT_COUNT, /* 6 OFFSET : 74 -85 bytes */
- VS_ATTR_LIFETIME_ENTERING_PS4_COUNT, /* 7 OFFSET : 86 -97 bytes */
- VS_ATTR_LIFETIME_ENTERING_PS3_COUNT, /* 8 OFFSET : 98 -109 bytes */
- VS_ATTR_RETIRED_BLOCK_COUNT, /* 9 OFFSET : 110 -121 bytes */
- VS_ATTR_PROGRAM_FAILURE_COUNT, /* 10 OFFSET : 122 -133 bytes */
- VS_ATTR_ERASE_FAIL_COUNT, /* 11 OFFSET : 134 -145 bytes */
- VS_ATTR_AVG_ERASE_COUNT, /* 12 OFFSET : 146 -157 bytes */
- VS_ATTR_UNEXPECTED_POWER_LOSS_COUNT, /* 13 OFFSET : 158 -169 bytes */
- VS_ATTR_WEAR_RANGE_DELTA, /* 14 OFFSET : 170 -181 bytes */
- VS_ATTR_SATA_INTERFACE_DOWNSHIFT_COUNT, /* 15 OFFSET : 182 -193 bytes */
- VS_ATTR_END_TO_END_CRC_ERROR_COUNT, /* 16 OFFSET : 194 -205 bytes */
- VS_ATTR_MAX_LIFE_TEMPERATURE, /* 17 OFFSET : 206 -217 bytes */
- VS_ATTR_UNCORRECTABLE_RAISE_ERRORS, /* 18 OFFSET : 218 -229 bytes */
- VS_ATTR_DRIVE_LIFE_PROTECTION_STATUS, /* 19 OFFSET : 230 -241 bytes */
- VS_ATTR_REMAINING_SSD_LIFE, /* 20 OFFSET : 242 -253 bytes */
- VS_ATTR_LIFETIME_WRITES_TO_FLASH, /* 21 OFFSET : 254 -265 bytes */
- VS_ATTR_LIFETIME_WRITES_FROM_HOST, /* 22 OFFSET : 266 -277 bytes */
- VS_ATTR_LIFETIME_READS_TO_HOST, /* 23 OFFSET : 278 -289 bytes */
- VS_ATTR_FREE_SPACE, /* 24 OFFSET : 290 -301 bytes */
- VS_ATTR_TRIM_COUNT_LSB, /* 25 OFFSET : 302 -313 bytes */
- VS_ATTR_TRIM_COUNT_MSB, /* 26 OFFSET : 314 -325 bytes */
- VS_ATTR_OP_PERCENTAGE, /* 27 OFFSET : 326 -337 bytes */
- VS_ATTR_RAISE_ECC_CORRECTABLE_ERROR_COUNT, /* 28 OFFSET : 338 -349 bytes */
- VS_ATTR_UNCORRECTABLE_ECC_ERRORS , /* 29 OFFSET : 350 -361 bytes */
- VS_ATTR_LIFETIME_WRITES0_TO_FLASH, /* 30 362-372 */
- VS_ATTR_LIFETIME_WRITES1_TO_FLASH, /* 31 374-385 */
- VS_ATTR_LIFETIME_WRITES0_FROM_HOST, /* 32 386-397 */
- VS_ATTR_LIFETIME_WRITES1_FROM_HOST, /* 33 398-409 */
- VS_ATTR_LIFETIME_READ0_FROM_HOST, /* 34 410-421 */
- VS_ATTR_LIFETIME_READ1_FROM_HOST, /* 35 422-433 */
- VS_ATTR_PCIE_PHY_CRC_ERROR, /* 36 434-445 */
- VS_ATTR_BAD_BLOCK_COUNT_SYSTEM, /* 37 446-457 */
- VS_ATTR_BAD_BLOCK_COUNT_USER, /* 38 458-469 */
- VS_ATTR_THERMAL_THROTTLING_STATUS, /* 39 470-481 */
- VS_ATTR_POWER_CONSUMPTION, /* 40 482-493 */
- VS_ATTR_MAX_SOC_LIFE_TEMPERATURE, /* 41 494-505 */
-
- VS_MAX_ATTR_NUMBER,
-
+ VS_ATTR_LIFETIME_ENTERING_PS4_COUNT, /* 7 OFFSET : 86 -97 bytes */
+ VS_ATTR_LIFETIME_ENTERING_PS3_COUNT, /* 8 OFFSET : 98 -109 bytes */
+ VS_ATTR_RETIRED_BLOCK_COUNT, /* 9 OFFSET : 110 -121 bytes */
+ VS_ATTR_PROGRAM_FAILURE_COUNT, /* 10 OFFSET : 122 -133 bytes */
+ VS_ATTR_ERASE_FAIL_COUNT, /* 11 OFFSET : 134 -145 bytes */
+ VS_ATTR_AVG_ERASE_COUNT, /* 12 OFFSET : 146 -157 bytes */
+ VS_ATTR_UNEXPECTED_POWER_LOSS_COUNT, /* 13 OFFSET : 158 -169 bytes */
+ VS_ATTR_WEAR_RANGE_DELTA, /* 14 OFFSET : 170 -181 bytes */
+ VS_ATTR_SATA_INTERFACE_DOWNSHIFT_COUNT, /* 15 OFFSET : 182 -193 bytes */
+ VS_ATTR_END_TO_END_CRC_ERROR_COUNT, /* 16 OFFSET : 194 -205 bytes */
+ VS_ATTR_MAX_LIFE_TEMPERATURE, /* 17 OFFSET : 206 -217 bytes */
+ VS_ATTR_UNCORRECTABLE_RAISE_ERRORS, /* 18 OFFSET : 218 -229 bytes */
+ VS_ATTR_DRIVE_LIFE_PROTECTION_STATUS, /* 19 OFFSET : 230 -241 bytes */
+ VS_ATTR_REMAINING_SSD_LIFE, /* 20 OFFSET : 242 -253 bytes */
+ VS_ATTR_LIFETIME_WRITES_TO_FLASH, /* 21 OFFSET : 254 -265 bytes */
+ VS_ATTR_LIFETIME_WRITES_FROM_HOST, /* 22 OFFSET : 266 -277 bytes */
+ VS_ATTR_LIFETIME_READS_TO_HOST, /* 23 OFFSET : 278 -289 bytes */
+ VS_ATTR_FREE_SPACE, /* 24 OFFSET : 290 -301 bytes */
+ VS_ATTR_TRIM_COUNT_LSB, /* 25 OFFSET : 302 -313 bytes */
+ VS_ATTR_TRIM_COUNT_MSB, /* 26 OFFSET : 314 -325 bytes */
+ VS_ATTR_OP_PERCENTAGE, /* 27 OFFSET : 326 -337 bytes */
+ VS_ATTR_RAISE_ECC_CORRECTABLE_ERROR_COUNT, /* 28 OFFSET : 338 -349 bytes */
+ VS_ATTR_UNCORRECTABLE_ECC_ERRORS , /* 29 OFFSET : 350 -361 bytes */
+ VS_ATTR_LIFETIME_WRITES0_TO_FLASH, /* 30 OFFSET : 362-372 bytes */
+ VS_ATTR_LIFETIME_WRITES1_TO_FLASH, /* 31 OFFSET : 374-385 bytes */
+ VS_ATTR_LIFETIME_WRITES0_FROM_HOST, /* 32 OFFSET : 386-397 bytes */
+ VS_ATTR_LIFETIME_WRITES1_FROM_HOST, /* 33 OFFSET : 398-409 bytes */
+ VS_ATTR_LIFETIME_READ0_FROM_HOST, /* 34 OFFSET : 410-421 bytes */
+ VS_ATTR_LIFETIME_READ1_FROM_HOST, /* 35 OFFSET : 422-433 bytes */
+ VS_ATTR_PCIE_PHY_CRC_ERROR, /* 36 OFFSET : 434-445 bytes */
+ VS_ATTR_BAD_BLOCK_COUNT_SYSTEM, /* 37 OFFSET : 446-457 bytes */
+ VS_ATTR_BAD_BLOCK_COUNT_USER, /* 38 OFFSET : 458-469 bytes */
+ VS_ATTR_THERMAL_THROTTLING_STATUS, /* 39 OFFSET : 470-481 bytes */
+ VS_ATTR_POWER_CONSUMPTION, /* 40 OFFSET : 482-493 bytes */
+ VS_ATTR_MAX_SOC_LIFE_TEMPERATURE, /* 41 OFFSET : 494-505 bytes */
+ VS_MAX_ATTR_NUMBER
} extended_smart_attributes;
/*Smart attribute IDs */
diff --git a/plugins/seagate/seagate-nvme.c b/plugins/seagate/seagate-nvme.c
index a527c0f..1bd30a5 100644
--- a/plugins/seagate/seagate-nvme.c
+++ b/plugins/seagate/seagate-nvme.c
@@ -18,6 +18,8 @@
*
* \file seagate-nvme.c
* \brief This file defines the functions and macros to make building a nvme-cli seagate plug-in.
+ *
+ * Author: Debabrata Bardhan <debabrata.bardhan@seagate.com>
*/
@@ -25,6 +27,7 @@
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
#include <inttypes.h>
#include <sys/stat.h>
@@ -35,6 +38,7 @@
#include "plugin.h"
#include "linux/types.h"
#include "nvme-print.h"
+#include <time.h>
#define CREATE_CMD
@@ -43,11 +47,11 @@
/***************************************
-*Command for "log-pages-supp"
-***************************************/
+ * Command for "log-pages-supp"
+ ***************************************/
static char *log_pages_supp_print(__u32 pageID)
{
- switch(pageID) {
+ switch (pageID) {
case 0x01:
return "ERROR_INFORMATION";
break;
@@ -126,6 +130,20 @@ static char *log_pages_supp_print(__u32 pageID)
}
}
+static int stx_is_jag_pan(char *devMN)
+{
+ int match_found = 1; /* found = 0, not_found = 1 */
+
+ for (int i = 0; i < STX_NUM_LEGACY_DRV; i++) {
+ match_found = strncmp(devMN, stx_jag_pan_mn[i], strlen(stx_jag_pan_mn[i]));
+ if (match_found == 0) {
+ break;
+ }
+ }
+
+ return match_found;
+}
+
static void json_log_pages_supp(log_page_map *logPageMap)
{
@@ -147,19 +165,18 @@ static void json_log_pages_supp(log_page_map *logPageMap)
json_array_add_value_object(logPages, lbaf);
}
json_print_object(root, NULL);
- printf("\n");
json_free_object(root);
}
static int log_pages_supp(int argc, char **argv, struct command *cmd,
- struct plugin *plugin)
+ struct plugin *plugin)
{
int err = 0;
- int fd = 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;
int fmt;
struct config {
@@ -175,35 +192,36 @@ static int log_pages_supp(int argc, char **argv, struct command *cmd,
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
- err = nvme_get_log_simple(fd, 0xc5, sizeof(logPageMap), &logPageMap);
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
+ err = nvme_get_log_simple(dev_fd(dev), 0xc5,
+ sizeof(logPageMap), &logPageMap);
if (!err) {
- if (strcmp(cfg.output_format,"json")) {
+ if (strcmp(cfg.output_format, "json")) {
printf ("Seagate Supported Log-pages count :%d\n",
le32_to_cpu(logPageMap.NumLogPages));
printf ("%-15s %-30s\n", "LogPage-Id", "LogPage-Name");
- for(fmt=0; fmt<45; fmt++)
- printf ("-");
+ for (fmt = 0; fmt < 45; fmt++)
+ printf("-");
printf("\n");
} else
json_log_pages_supp(&logPageMap);
- for (i = 0; i<le32_to_cpu(logPageMap.NumLogPages); i++) {
- if (strcmp(cfg.output_format,"json")) {
+ for (i = 0; i < le32_to_cpu(logPageMap.NumLogPages); i++) {
+ if (strcmp(cfg.output_format, "json")) {
printf("0x%-15X",
- le32_to_cpu(logPageMap.LogPageEntry[i].LogPageID));
+ le32_to_cpu(logPageMap.LogPageEntry[i].LogPageID));
printf("%-30s\n",
- log_pages_supp_print(le32_to_cpu(logPageMap.LogPageEntry[i].LogPageID)));
+ log_pages_supp_print(le32_to_cpu(logPageMap.LogPageEntry[i].LogPageID)));
}
}
}
if (err > 0)
nvme_show_status(err);
- close(fd);
+ dev_close(dev);
return err;
}
@@ -215,7 +233,7 @@ static int log_pages_supp(int argc, char **argv, struct command *cmd,
***************************************/
static char *print_ext_smart_id(__u8 attrId)
{
- switch(attrId) {
+ switch (attrId) {
case VS_ATTR_ID_SOFT_READ_ERROR_RATE:
return "Soft ECC error count";
break;
@@ -280,7 +298,7 @@ static char *print_ext_smart_id(__u8 attrId)
return "LIFETIME_ENTERING_PS3_COUNT";
break;
case VS_ATTR_ID_RETIRED_BLOCK_COUNT:
- return "Retired block count"; /*VS_ATTR_ID_RETIRED_BLOCK_COUNT*/
+ return "Retired block count";
break;
case VS_ATTR_ID_PROGRAM_FAILURE_COUNT:
return "Program fail count";
@@ -307,13 +325,13 @@ static char *print_ext_smart_id(__u8 attrId)
return "Uncorrectable Read Error Count";
break;
case VS_ATTR_ID_MAX_LIFE_TEMPERATURE:
- return "Max lifetime temperature";/*VS_ATTR_ID_MAX_LIFE_TEMPERATURE for extended*/
+ return "Max lifetime temperature";
break;
case VS_ATTR_ID_RAISE_ECC_CORRECTABLE_ERROR_COUNT:
return "RAIS_ECC_CORRECT_ERR_COUNT";
break;
case VS_ATTR_ID_UNCORRECTABLE_RAISE_ERRORS:
- return "Uncorrectable RAISE error count";/*VS_ATTR_ID_UNCORRECTABLE_RAISE_ERRORS*/
+ return "Uncorrectable RAISE error count";
break;
case VS_ATTR_ID_DRIVE_LIFE_PROTECTION_STATUS:
return "DRIVE_LIFE_PROTECTION_STATUS";
@@ -356,7 +374,7 @@ static char *print_ext_smart_id(__u8 attrId)
break;
default:
return "Un-Known";
- }
+ }
}
static __u64 smart_attribute_vs(__u16 verNo, SmartVendorSpecific attr)
@@ -435,9 +453,8 @@ static void print_smart_log(__u16 verNo, SmartVendorSpecific attr, int lastAttr)
if ((attr.AttributeNumber != 0) && (hideAttr != 1)) {
printf("%-40s", print_ext_smart_id(attr.AttributeNumber));
- printf("%-15d", attr.AttributeNumber );
- printf(" 0x%016"PRIx64"", (uint64_t)smart_attribute_vs(verNo, attr));
- printf("\n");
+ printf("%-15d", attr.AttributeNumber);
+ printf(" 0x%016"PRIx64"\n", (uint64_t)smart_attribute_vs(verNo, attr));
}
if (lastAttr == 1) {
@@ -448,8 +465,7 @@ static void print_smart_log(__u16 verNo, SmartVendorSpecific attr, int lastAttr)
printf("%-15d", VS_ATTR_ID_GB_ERASED_MSB << 8 | VS_ATTR_ID_GB_ERASED_LSB);
sprintf(buf, "0x%016"PRIx64"%016"PRIx64"", (uint64_t)msbGbErased, (uint64_t)lsbGbErased);
- printf(" %s", buf);
- printf("\n");
+ printf(" %s\n", buf);
sprintf(strBuf, "%s", (print_ext_smart_id(VS_ATTR_ID_LIFETIME_WRITES_TO_FLASH_LSB) + 7));
printf("%-40s", strBuf);
@@ -457,8 +473,7 @@ static void print_smart_log(__u16 verNo, SmartVendorSpecific attr, int lastAttr)
printf("%-15d", VS_ATTR_ID_LIFETIME_WRITES_TO_FLASH_MSB << 8 | VS_ATTR_ID_LIFETIME_WRITES_TO_FLASH_LSB);
sprintf(buf, "0x%016"PRIx64"%016"PRIx64"", (uint64_t)msbLifWrtToFlash, (uint64_t)lsbLifWrtToFlash);
- printf(" %s", buf);
- printf("\n");
+ printf(" %s\n", buf);
sprintf(strBuf, "%s", (print_ext_smart_id(VS_ATTR_ID_LIFETIME_WRITES_FROM_HOST_LSB) + 7));
printf("%-40s", strBuf);
@@ -466,8 +481,7 @@ static void print_smart_log(__u16 verNo, SmartVendorSpecific attr, int lastAttr)
printf("%-15d", VS_ATTR_ID_LIFETIME_WRITES_FROM_HOST_MSB << 8 | VS_ATTR_ID_LIFETIME_WRITES_FROM_HOST_LSB);
sprintf(buf, "0x%016"PRIx64"%016"PRIx64"", (uint64_t)msbLifWrtFrmHost, (uint64_t)lsbLifWrtFrmHost);
- printf(" %s", buf);
- printf("\n");
+ printf(" %s\n", buf);
sprintf(strBuf, "%s", (print_ext_smart_id(VS_ATTR_ID_LIFETIME_READS_TO_HOST_LSB) + 7));
printf("%-40s", strBuf);
@@ -475,8 +489,7 @@ static void print_smart_log(__u16 verNo, SmartVendorSpecific attr, int lastAttr)
printf("%-15d", VS_ATTR_ID_LIFETIME_READS_TO_HOST_MSB << 8 | VS_ATTR_ID_LIFETIME_READS_TO_HOST_LSB);
sprintf(buf, "0x%016"PRIx64"%016"PRIx64"", (uint64_t)msbLifRdToHost, (uint64_t)lsbLifRdToHost);
- printf(" %s", buf);
- printf("\n");
+ printf(" %s\n", buf);
sprintf(strBuf, "%s", (print_ext_smart_id(VS_ATTR_ID_TRIM_COUNT_LSB) + 7));
printf("%-40s", strBuf);
@@ -484,16 +497,13 @@ static void print_smart_log(__u16 verNo, SmartVendorSpecific attr, int lastAttr)
printf("%-15d", VS_ATTR_ID_TRIM_COUNT_MSB << 8 | VS_ATTR_ID_TRIM_COUNT_LSB);
sprintf(buf, "0x%016"PRIx64"%016"PRIx64"", (uint64_t)msbTrimCnt, (uint64_t)lsbTrimCnt);
- printf(" %s", buf);
- printf("\n");
+ printf(" %s\n", buf);
}
}
-static void json_print_smart_log(struct json_object *root,
- EXTENDED_SMART_INFO_T *ExtdSMARTInfo )
+static void json_print_smart_log(struct json_object *root, EXTENDED_SMART_INFO_T *ExtdSMARTInfo)
{
- /*struct json_object *root; */
struct json_object *lbafs;
int index = 0;
@@ -501,46 +511,45 @@ static void json_print_smart_log(struct json_object *root,
lsbLifWrtFrmHost = 0, msbLifWrtFrmHost = 0, lsbLifRdToHost = 0, msbLifRdToHost = 0, lsbTrimCnt = 0, msbTrimCnt = 0;
char buf[40] = {0};
- /*root = json_create_object();*/
lbafs = json_create_array();
json_object_add_value_array(root, "Extended-SMART-Attributes", lbafs);
- for (index =0; index < NUMBER_EXTENDED_SMART_ATTRIBUTES; index++) {
+ for (index = 0; index < NUMBER_EXTENDED_SMART_ATTRIBUTES; index++) {
struct json_object *lbaf = json_create_object();
if (ExtdSMARTInfo->vendorData[index].AttributeNumber != 0) {
json_object_add_value_string(lbaf, "attribute_name", print_ext_smart_id(ExtdSMARTInfo->vendorData[index].AttributeNumber));
- json_object_add_value_int(lbaf, "attribute_id",ExtdSMARTInfo->vendorData[index].AttributeNumber);
+ json_object_add_value_int(lbaf, "attribute_id", ExtdSMARTInfo->vendorData[index].AttributeNumber);
json_object_add_value_int(lbaf, "attribute_value", smart_attribute_vs(ExtdSMARTInfo->Version, ExtdSMARTInfo->vendorData[index]));
json_array_add_value_object(lbafs, lbaf);
- if(ExtdSMARTInfo->vendorData[index].AttributeNumber == VS_ATTR_ID_GB_ERASED_LSB)
+ if (ExtdSMARTInfo->vendorData[index].AttributeNumber == VS_ATTR_ID_GB_ERASED_LSB)
lsbGbErased = smart_attribute_vs(ExtdSMARTInfo->Version, ExtdSMARTInfo->vendorData[index]);
- if(ExtdSMARTInfo->vendorData[index].AttributeNumber == VS_ATTR_ID_GB_ERASED_MSB)
+ if (ExtdSMARTInfo->vendorData[index].AttributeNumber == VS_ATTR_ID_GB_ERASED_MSB)
msbGbErased = smart_attribute_vs(ExtdSMARTInfo->Version, ExtdSMARTInfo->vendorData[index]);
- if(ExtdSMARTInfo->vendorData[index].AttributeNumber == VS_ATTR_ID_LIFETIME_WRITES_TO_FLASH_LSB)
+ if (ExtdSMARTInfo->vendorData[index].AttributeNumber == VS_ATTR_ID_LIFETIME_WRITES_TO_FLASH_LSB)
lsbLifWrtToFlash = smart_attribute_vs(ExtdSMARTInfo->Version, ExtdSMARTInfo->vendorData[index]);
- if(ExtdSMARTInfo->vendorData[index].AttributeNumber == VS_ATTR_ID_LIFETIME_WRITES_TO_FLASH_MSB)
+ if (ExtdSMARTInfo->vendorData[index].AttributeNumber == VS_ATTR_ID_LIFETIME_WRITES_TO_FLASH_MSB)
msbLifWrtToFlash = smart_attribute_vs(ExtdSMARTInfo->Version, ExtdSMARTInfo->vendorData[index]);
- if(ExtdSMARTInfo->vendorData[index].AttributeNumber == VS_ATTR_ID_LIFETIME_WRITES_FROM_HOST_LSB)
+ if (ExtdSMARTInfo->vendorData[index].AttributeNumber == VS_ATTR_ID_LIFETIME_WRITES_FROM_HOST_LSB)
lsbLifWrtFrmHost = smart_attribute_vs(ExtdSMARTInfo->Version, ExtdSMARTInfo->vendorData[index]);
- if(ExtdSMARTInfo->vendorData[index].AttributeNumber == VS_ATTR_ID_LIFETIME_WRITES_FROM_HOST_MSB)
+ if (ExtdSMARTInfo->vendorData[index].AttributeNumber == VS_ATTR_ID_LIFETIME_WRITES_FROM_HOST_MSB)
msbLifWrtFrmHost = smart_attribute_vs(ExtdSMARTInfo->Version, ExtdSMARTInfo->vendorData[index]);
- if(ExtdSMARTInfo->vendorData[index].AttributeNumber == VS_ATTR_ID_LIFETIME_READS_TO_HOST_LSB)
+ if (ExtdSMARTInfo->vendorData[index].AttributeNumber == VS_ATTR_ID_LIFETIME_READS_TO_HOST_LSB)
lsbLifRdToHost = smart_attribute_vs(ExtdSMARTInfo->Version, ExtdSMARTInfo->vendorData[index]);
- if(ExtdSMARTInfo->vendorData[index].AttributeNumber == VS_ATTR_ID_LIFETIME_READS_TO_HOST_MSB)
+ if (ExtdSMARTInfo->vendorData[index].AttributeNumber == VS_ATTR_ID_LIFETIME_READS_TO_HOST_MSB)
msbLifRdToHost = smart_attribute_vs(ExtdSMARTInfo->Version, ExtdSMARTInfo->vendorData[index]);
- if(ExtdSMARTInfo->vendorData[index].AttributeNumber == VS_ATTR_ID_TRIM_COUNT_LSB)
+ if (ExtdSMARTInfo->vendorData[index].AttributeNumber == VS_ATTR_ID_TRIM_COUNT_LSB)
lsbTrimCnt = smart_attribute_vs(ExtdSMARTInfo->Version, ExtdSMARTInfo->vendorData[index]);
- if(ExtdSMARTInfo->vendorData[index].AttributeNumber == VS_ATTR_ID_TRIM_COUNT_MSB)
+ if (ExtdSMARTInfo->vendorData[index].AttributeNumber == VS_ATTR_ID_TRIM_COUNT_MSB)
msbTrimCnt = smart_attribute_vs(ExtdSMARTInfo->Version, ExtdSMARTInfo->vendorData[index]);
}
}
@@ -598,11 +607,6 @@ static void json_print_smart_log(struct json_object *root,
sprintf(buf, "0x%016"PRIx64"%016"PRIx64"", (uint64_t)msbTrimCnt, (uint64_t)lsbTrimCnt);
json_object_add_value_string(lbaf, "attribute_value", buf);
json_array_add_value_object(lbafs, lbaf);
-
- /*
- json_print_object(root, NULL);
- printf("\n");
- */
}
static void print_smart_log_CF(vendor_log_page_CF *pLogPageCF)
@@ -613,63 +617,47 @@ static void print_smart_log_CF(vendor_log_page_CF *pLogPageCF)
printf("%-40s", "Super-cap current temperature");
currentTemp = pLogPageCF->AttrCF.SuperCapCurrentTemperature;
- /*currentTemp = currentTemp ? currentTemp - 273 : 0;*/
- printf(" 0x%016"PRIx64"", le64_to_cpu(currentTemp));
- printf("\n");
+ printf(" 0x%016"PRIx64"\n", le64_to_cpu(currentTemp));
maxTemp = pLogPageCF->AttrCF.SuperCapMaximumTemperature;
- /*maxTemp = maxTemp ? maxTemp - 273 : 0;*/
printf("%-40s", "Super-cap maximum temperature");
- printf(" 0x%016"PRIx64"", le64_to_cpu(maxTemp));
- printf("\n");
+ printf(" 0x%016"PRIx64"\n", le64_to_cpu(maxTemp));
printf("%-40s", "Super-cap status");
- printf(" 0x%016"PRIx64"", le64_to_cpu(pLogPageCF->AttrCF.SuperCapStatus));
- printf("\n");
+ printf(" 0x%016"PRIx64"\n", le64_to_cpu(pLogPageCF->AttrCF.SuperCapStatus));
printf("%-40s", "Data units read to DRAM namespace");
- printf(" 0x%016"PRIx64"%016"PRIx64"", le64_to_cpu(pLogPageCF->AttrCF.DataUnitsReadToDramNamespace.MS__u64),
- le64_to_cpu(pLogPageCF->AttrCF.DataUnitsReadToDramNamespace.LS__u64));
- printf("\n");
+ printf(" 0x%016"PRIx64"%016"PRIx64"\n", le64_to_cpu(pLogPageCF->AttrCF.DataUnitsReadToDramNamespace.MS__u64),
+ le64_to_cpu(pLogPageCF->AttrCF.DataUnitsReadToDramNamespace.LS__u64));
printf("%-40s", "Data units written to DRAM namespace");
- printf(" 0x%016"PRIx64"%016"PRIx64"", le64_to_cpu(pLogPageCF->AttrCF.DataUnitsWrittenToDramNamespace.MS__u64),
- le64_to_cpu(pLogPageCF->AttrCF.DataUnitsWrittenToDramNamespace.LS__u64));
- printf("\n");
+ printf(" 0x%016"PRIx64"%016"PRIx64"\n", le64_to_cpu(pLogPageCF->AttrCF.DataUnitsWrittenToDramNamespace.MS__u64),
+ le64_to_cpu(pLogPageCF->AttrCF.DataUnitsWrittenToDramNamespace.LS__u64));
printf("%-40s", "DRAM correctable error count");
- printf(" 0x%016"PRIx64"", le64_to_cpu(pLogPageCF->AttrCF.DramCorrectableErrorCount));
- printf("\n");
+ printf(" 0x%016"PRIx64"\n", le64_to_cpu(pLogPageCF->AttrCF.DramCorrectableErrorCount));
printf("%-40s", "DRAM uncorrectable error count");
- printf(" 0x%016"PRIx64"", le64_to_cpu(pLogPageCF->AttrCF.DramUncorrectableErrorCount));
- printf("\n");
-
+ printf(" 0x%016"PRIx64"\n", le64_to_cpu(pLogPageCF->AttrCF.DramUncorrectableErrorCount));
}
-static void json_print_smart_log_CF(struct json_object *root,
- vendor_log_page_CF *pLogPageCF)
+static void json_print_smart_log_CF(struct json_object *root, vendor_log_page_CF *pLogPageCF)
{
- /*struct json_object *root;*/
struct json_object *logPages;
unsigned int currentTemp, maxTemp;
char buf[40];
- /*root = json_create_object(); */
-
logPages = json_create_array();
json_object_add_value_array(root, "DRAM Supercap SMART Attributes", logPages);
struct json_object *lbaf = json_create_object();
currentTemp = pLogPageCF->AttrCF.SuperCapCurrentTemperature;
- /*currentTemp = currentTemp ? currentTemp - 273 : 0;*/
json_object_add_value_string(lbaf, "attribute_name", "Super-cap current temperature");
json_object_add_value_int(lbaf, "attribute_value", currentTemp);
json_array_add_value_object(logPages, lbaf);
lbaf = json_create_object();
maxTemp = pLogPageCF->AttrCF.SuperCapMaximumTemperature;
- /*maxTemp = maxTemp ? maxTemp - 273 : 0;*/
json_object_add_value_string(lbaf, "attribute_name", "Super-cap maximum temperature");
json_object_add_value_int(lbaf, "attribute_value", maxTemp);
json_array_add_value_object(logPages, lbaf);
@@ -704,25 +692,285 @@ static void json_print_smart_log_CF(struct json_object *root,
json_object_add_value_string(lbaf, "attribute_name", "DRAM uncorrectable error count");
json_object_add_value_int(lbaf, "attribute_value", pLogPageCF->AttrCF.DramUncorrectableErrorCount);
json_array_add_value_object(logPages, lbaf);
+}
+
+
+static void print_stx_smart_log_C0(STX_EXT_SMART_LOG_PAGE_C0 *pLogPageC0)
+{
+ printf("\n\nSeagate SMART Health Attributes :\n");
+ printf("%-39s %-19s \n", "Description", "Health Attributes");
+
+ printf("%-40s", "Physical Media Units Written");
+ printf(" 0x%016"PRIx64"%016"PRIx64"\n", le64_to_cpu(pLogPageC0->phyMediaUnitsWrt.MS__u64),
+ le64_to_cpu(pLogPageC0->phyMediaUnitsWrt.LS__u64));
+
+ printf("%-40s", "Physical Media Units Read");
+ printf(" 0x%016"PRIx64"%016"PRIx64"\n", le64_to_cpu(pLogPageC0->phyMediaUnitsRd.MS__u64),
+ le64_to_cpu(pLogPageC0->phyMediaUnitsRd.LS__u64));
+
+ printf("%-40s", "Bad User NAND Blocks");
+ printf(" 0x%016"PRIx64"\n", le64_to_cpu(pLogPageC0->badUsrNandBlocks));
+
+ printf("%-40s", "Bad System NAND Blocks");
+ printf(" 0x%016"PRIx64"\n", le64_to_cpu(pLogPageC0->badSysNandBlocks));
+
+ printf("%-40s", "XOR Recovery Count");
+ printf(" 0x%016"PRIx64"\n", le64_to_cpu(pLogPageC0->xorRecoveryCnt));
+
+ printf("%-40s", "Uncorrectable Read Error Count");
+ printf(" 0x%016"PRIx64"\n", le64_to_cpu(pLogPageC0->ucRdEc));
+
+ printf("%-40s", "Soft ECC Error Count");
+ printf(" 0x%016"PRIx64"\n", le64_to_cpu(pLogPageC0->softEccEc));
+
+ printf("%-40s", "End to End Correction Counts");
+ printf(" 0x%016"PRIx64"\n", le64_to_cpu(pLogPageC0->etoeCrrCnt));
+
+ printf("%-40s", "System Data Used in Parcent");
+ printf(" 0x%016"PRIx64"\n", le64_to_cpu(pLogPageC0->sysDataUsed));
+
+ printf("%-40s", "Refresh Counts");
+ printf(" 0x%016"PRIx64"\n", le64_to_cpu(pLogPageC0->refreshCount));
+
+ printf("%-40s", "User Data Erase Counts");
+ printf(" 0x%016"PRIx64"\n", le64_to_cpu(pLogPageC0->usrDataEraseCnt));
+
+ printf("%-40s", "Thermal Throttling Status and Count");
+ printf(" 0x%04x\n", le16_to_cpu(pLogPageC0->thermalThrottling));
+
+ printf("%-40s", "DSSD Specification Version");
+ printf(" %d.%d.%d.%d\n", pLogPageC0->dssdSpecVerMajor,
+ le16_to_cpu(pLogPageC0->dssdSpecVerMinor),
+ le16_to_cpu(pLogPageC0->dssdSpecVerPoint),
+ pLogPageC0->dssdSpecVerErrata);
+
+ printf("%-40s", "PCIe Correctable Error Count");
+ printf(" 0x%016"PRIx64"\n", le64_to_cpu(pLogPageC0->pcieCorrEc));
+
+ printf("%-40s", "Incomplete Shutdowns");
+ printf(" 0x%08x\n", le32_to_cpu(pLogPageC0->incompleteShutdowns));
+
+ printf("%-40s", "Free Blocks in Percent");
+ printf(" %d\n", pLogPageC0->freeBlocks);
+
+ printf("%-40s", "Capacitor Health");
+ printf(" 0x%04x\n", le16_to_cpu(pLogPageC0->capHealth));
+
+ printf("%-40s", "NVMe Errata Version");
+ printf(" %c\n", pLogPageC0->nvmeErrataVer);
+
+ printf("%-40s", "Unaligned IO");
+ printf(" 0x%016"PRIx64"\n", le64_to_cpu(pLogPageC0->unalignedIO));
+
+ printf("%-40s", "Security Version Number");
+ printf(" 0x%016"PRIx64"\n", le64_to_cpu(pLogPageC0->secVerNum));
+
+ printf("%-40s", "Total Namespace Utilization");
+ printf(" 0x%016"PRIx64"\n", le64_to_cpu(pLogPageC0->totalNUSE));
+
+ printf("%-40s", "PLP Start Count");
+ printf(" 0x%016"PRIx64"%016"PRIx64"\n", le64_to_cpu(pLogPageC0->plpStartCnt.MS__u64),
+ le64_to_cpu(pLogPageC0->plpStartCnt.LS__u64));
+
+ printf("%-40s", "Endurance Estimate");
+ printf(" 0x%016"PRIx64"%016"PRIx64"\n", le64_to_cpu(pLogPageC0->enduranceEstimate.MS__u64),
+ le64_to_cpu(pLogPageC0->enduranceEstimate.LS__u64));
+
+ printf("%-40s", "PCIe Link Retraining Count");
+ printf(" 0x%016"PRIx64"\n", le64_to_cpu(pLogPageC0->pcieLinkRetCnt));
+
+ printf("%-40s", "Power State Change Count");
+ printf(" 0x%016"PRIx64"\n", le64_to_cpu(pLogPageC0->powStateChangeCnt));
+
+ printf("%-40s", "Log Page Version");
+ printf(" 0x%04x\n", le16_to_cpu(pLogPageC0->logPageVer));
+
+ printf("%-40s", "Log Page GUID");
+ printf(" 0x%016"PRIx64"%016"PRIx64"\n", le64_to_cpu(pLogPageC0->logPageGUID.MS__u64),
+ le64_to_cpu(pLogPageC0->logPageGUID.LS__u64));
+}
+
+static void json_print_stx_smart_log_C0(struct json_object *root, STX_EXT_SMART_LOG_PAGE_C0 *pLogPageC0)
+{
+ struct json_object *logPages;
+ char buf[40];
+
+ logPages = json_create_array();
+ json_object_add_value_array(root, "Seagate SMART Health Attributes", logPages);
+
+ struct json_object *lbaf = json_create_object();
+
+ json_object_add_value_string(lbaf, "attribute_name", "Physical Media Units Written");
+ memset(buf, 0, sizeof(buf));
+ sprintf(buf, "0x%016"PRIx64"%016"PRIx64"", le64_to_cpu(pLogPageC0->phyMediaUnitsWrt.MS__u64),
+ le64_to_cpu(pLogPageC0->phyMediaUnitsWrt.LS__u64));
+ json_object_add_value_string(lbaf, "attribute_value", buf);
+ json_array_add_value_object(logPages, lbaf);
+
+
+ lbaf = json_create_object();
+ json_object_add_value_string(lbaf, "attribute_name", "Physical Media Units Read");
+ memset(buf, 0, sizeof(buf));
+ sprintf(buf, "0x%016"PRIx64"%016"PRIx64"", le64_to_cpu(pLogPageC0->phyMediaUnitsRd.MS__u64),
+ le64_to_cpu(pLogPageC0->phyMediaUnitsRd.LS__u64));
+ json_object_add_value_string(lbaf, "attribute_value", buf);
+ json_array_add_value_object(logPages, lbaf);
+
+ lbaf = json_create_object();
+ json_object_add_value_string(lbaf, "attribute_name", "Bad User NAND Blocks");
+ json_object_add_value_int(lbaf, "attribute_value", le64_to_cpu(pLogPageC0->badUsrNandBlocks));
+ json_array_add_value_object(logPages, lbaf);
+
+ lbaf = json_create_object();
+ json_object_add_value_string(lbaf, "attribute_name", "Bad System NAND Blocks");
+ json_object_add_value_int(lbaf, "attribute_value", le64_to_cpu(pLogPageC0->badSysNandBlocks));
+ json_array_add_value_object(logPages, lbaf);
+
+ lbaf = json_create_object();
+ json_object_add_value_string(lbaf, "attribute_name", "XOR Recovery Count");
+ json_object_add_value_int(lbaf, "attribute_value", le64_to_cpu(pLogPageC0->xorRecoveryCnt));
+ json_array_add_value_object(logPages, lbaf);
+
+ lbaf = json_create_object();
+ json_object_add_value_string(lbaf, "attribute_name", "Uncorrectable Read Error Count");
+ json_object_add_value_int(lbaf, "attribute_value", le64_to_cpu(pLogPageC0->ucRdEc));
+ json_array_add_value_object(logPages, lbaf);
+
+ lbaf = json_create_object();
+ json_object_add_value_string(lbaf, "attribute_name", "Soft ECC Error Count");
+ json_object_add_value_int(lbaf, "attribute_value", le64_to_cpu(pLogPageC0->softEccEc));
+ json_array_add_value_object(logPages, lbaf);
+
+ lbaf = json_create_object();
+ json_object_add_value_string(lbaf, "attribute_name", "End to End Correction Counts");
+ json_object_add_value_int(lbaf, "attribute_value", le64_to_cpu(pLogPageC0->etoeCrrCnt));
+ json_array_add_value_object(logPages, lbaf);
+
+ lbaf = json_create_object();
+ json_object_add_value_string(lbaf, "attribute_name", "System Data Used in Parcent");
+ json_object_add_value_int(lbaf, "attribute_value", le64_to_cpu(pLogPageC0->sysDataUsed));
+ json_array_add_value_object(logPages, lbaf);
+
+ lbaf = json_create_object();
+ json_object_add_value_string(lbaf, "attribute_name", "Refresh Counts");
+ json_object_add_value_int(lbaf, "attribute_value", le64_to_cpu(pLogPageC0->refreshCount));
+ json_array_add_value_object(logPages, lbaf);
+
+ lbaf = json_create_object();
+ json_object_add_value_string(lbaf, "attribute_name", "User Data Erase Counts");
+ json_object_add_value_int(lbaf, "attribute_value", le64_to_cpu(pLogPageC0->usrDataEraseCnt));
+ json_array_add_value_object(logPages, lbaf);
+
+ lbaf = json_create_object();
+ json_object_add_value_string(lbaf, "attribute_name", "Thermal Throttling Status and Count");
+ json_object_add_value_int(lbaf, "attribute_value", le16_to_cpu(pLogPageC0->thermalThrottling));
+ json_array_add_value_object(logPages, lbaf);
+
+ lbaf = json_create_object();
+ json_object_add_value_string(lbaf, "attribute_name", "DSSD Specification Version");
+ memset(buf, 0, sizeof(buf));
+ sprintf(buf, "%d.%d.%d.%d", pLogPageC0->dssdSpecVerMajor,
+ le16_to_cpu(pLogPageC0->dssdSpecVerMinor),
+ le16_to_cpu(pLogPageC0->dssdSpecVerPoint),
+ pLogPageC0->dssdSpecVerErrata);
+ json_object_add_value_string(lbaf, "attribute_value", buf);
+ json_array_add_value_object(logPages, lbaf);
+
+ lbaf = json_create_object();
+ json_object_add_value_string(lbaf, "attribute_name", "PCIe Correctable Error Count");
+ json_object_add_value_int(lbaf, "attribute_value", le64_to_cpu(pLogPageC0->pcieCorrEc));
+ json_array_add_value_object(logPages, lbaf);
+
+ lbaf = json_create_object();
+ json_object_add_value_string(lbaf, "attribute_name", "Incomplete Shutdowns");
+ json_object_add_value_int(lbaf, "attribute_value", le32_to_cpu(pLogPageC0->incompleteShutdowns));
+ json_array_add_value_object(logPages, lbaf);
+
+ lbaf = json_create_object();
+ json_object_add_value_string(lbaf, "attribute_name", "Free Blocks in Percent");
+ json_object_add_value_int(lbaf, "attribute_value", pLogPageC0->freeBlocks);
+ json_array_add_value_object(logPages, lbaf);
+
+ lbaf = json_create_object();
+ json_object_add_value_string(lbaf, "attribute_name", "Capacitor Health");
+ json_object_add_value_int(lbaf, "attribute_value", le16_to_cpu(pLogPageC0->capHealth));
+ json_array_add_value_object(logPages, lbaf);
+
+ lbaf = json_create_object();
+ json_object_add_value_string(lbaf, "attribute_name", "NVMe Errata Version");
+ json_object_add_value_int(lbaf, "attribute_value", pLogPageC0->nvmeErrataVer);
+ json_array_add_value_object(logPages, lbaf);
+
+ lbaf = json_create_object();
+ json_object_add_value_string(lbaf, "attribute_name", "Unaligned IO");
+ json_object_add_value_int(lbaf, "attribute_value", le64_to_cpu(pLogPageC0->unalignedIO));
+ json_array_add_value_object(logPages, lbaf);
+
+ lbaf = json_create_object();
+ json_object_add_value_string(lbaf, "attribute_name", "Security Version Number");
+ json_object_add_value_int(lbaf, "attribute_value", le64_to_cpu(pLogPageC0->secVerNum));
+ json_array_add_value_object(logPages, lbaf);
+
+ lbaf = json_create_object();
+ json_object_add_value_string(lbaf, "attribute_name", "Total Namespace Utilization");
+ json_object_add_value_int(lbaf, "attribute_value", le64_to_cpu(pLogPageC0->totalNUSE));
+ json_array_add_value_object(logPages, lbaf);
+
+ lbaf = json_create_object();
+ json_object_add_value_string(lbaf, "attribute_name", "PLP Start Count");
+ memset(buf, 0, sizeof(buf));
+ sprintf(buf, "0x%016"PRIx64"%016"PRIx64"", le64_to_cpu(pLogPageC0->plpStartCnt.MS__u64),
+ le64_to_cpu(pLogPageC0->plpStartCnt.LS__u64));
+ json_object_add_value_string(lbaf, "attribute_value", buf);
+ json_array_add_value_object(logPages, lbaf);
+
+ lbaf = json_create_object();
+ json_object_add_value_string(lbaf, "attribute_name", "Endurance Estimate");
+ memset(buf, 0, sizeof(buf));
+ sprintf(buf, "0x%016"PRIx64"%016"PRIx64"", le64_to_cpu(pLogPageC0->enduranceEstimate.MS__u64),
+ le64_to_cpu(pLogPageC0->enduranceEstimate.LS__u64));
+ json_object_add_value_string(lbaf, "attribute_value", buf);
+ json_array_add_value_object(logPages, lbaf);
+
+ lbaf = json_create_object();
+ json_object_add_value_string(lbaf, "attribute_name", "PCIe Link Retraining Count");
+ json_object_add_value_int(lbaf, "attribute_value", le64_to_cpu(pLogPageC0->pcieLinkRetCnt));
+ json_array_add_value_object(logPages, lbaf);
+
+ lbaf = json_create_object();
+ json_object_add_value_string(lbaf, "attribute_name", "Power State Change Count");
+ json_object_add_value_int(lbaf, "attribute_value", le64_to_cpu(pLogPageC0->powStateChangeCnt));
+ json_array_add_value_object(logPages, lbaf);
+
+ lbaf = json_create_object();
+ json_object_add_value_string(lbaf, "attribute_name", "Log Page Version");
+ json_object_add_value_int(lbaf, "attribute_value", le16_to_cpu(pLogPageC0->logPageVer));
+ json_array_add_value_object(logPages, lbaf);
- /*
- json_print_object(root, NULL);
- printf("\n");
- */
+ lbaf = json_create_object();
+ json_object_add_value_string(lbaf, "attribute_name", "Log Page GUID");
+ memset(buf, 0, sizeof(buf));
+ sprintf(buf, "0x%016"PRIx64"%016"PRIx64"", le64_to_cpu(pLogPageC0->logPageGUID.MS__u64),
+ le64_to_cpu(pLogPageC0->logPageGUID.LS__u64));
+ json_object_add_value_string(lbaf, "attribute_value", buf);
+ json_array_add_value_object(logPages, lbaf);
}
static int vs_smart_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
+ struct nvme_id_ctrl ctrl;
+ char modelNo[40];
+ STX_EXT_SMART_LOG_PAGE_C0 ehExtSmart;
EXTENDED_SMART_INFO_T ExtdSMARTInfo;
vendor_log_page_CF logPageCF;
- int fd;
struct json_object *root = json_create_object();
struct json_object *lbafs = json_create_array();
struct json_object *lbafs_ExtSmart, *lbafs_DramSmart;
- const char *desc = "Retrieve Seagate Extended SMART information for the given device ";
+ const char *desc = "Retrieve the Firmware Activation History for Seagate NVMe drives";
const char *output_format = "output in binary format";
- int err, index=0;
+ struct nvme_dev *dev;
+ int err, index = 0;
struct config {
char *output_format;
};
@@ -736,23 +984,102 @@ static int vs_smart_log(int argc, char **argv, struct command *cmd, struct plugi
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0) {
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err) {
printf ("\nDevice not found \n");
return -1;
}
- if (strcmp(cfg.output_format,"json"))
+ if (strcmp(cfg.output_format, "json"))
printf("Seagate Extended SMART Information :\n");
- err = nvme_get_log_simple(fd, 0xC4, sizeof(ExtdSMARTInfo), &ExtdSMARTInfo);
+
+ /**
+ * Here we should identify if the drive is a Panthor or Jaguar.
+ * Here we need to extract the model no from ctrl-id abd use it
+ * to deternine drive family.
+ */
+
+ err = nvme_identify_ctrl(dev_fd(dev), &ctrl);
if (!err) {
- if (strcmp(cfg.output_format,"json")) {
+ memcpy(modelNo, ctrl.mn, sizeof(modelNo));
+ } else {
+ nvme_show_status(err);
+ return err;
+ }
+
+ if (stx_is_jag_pan(modelNo) == 0) {
+
+ err = nvme_get_log_simple(dev_fd(dev), 0xC4, sizeof(ExtdSMARTInfo), &ExtdSMARTInfo);
+ if (!err) {
+ if (strcmp(cfg.output_format, "json")) {
+ printf("%-39s %-15s %-19s \n", "Description", "Ext-Smart-Id", "Ext-Smart-Value");
+ for (index = 0; index < 80; index++)
+ printf("-");
+ printf("\n");
+ for (index = 0; index < NUMBER_EXTENDED_SMART_ATTRIBUTES; index++)
+ print_smart_log(ExtdSMARTInfo.Version, ExtdSMARTInfo.vendorData[index], index == (NUMBER_EXTENDED_SMART_ATTRIBUTES - 1));
+
+ } else {
+ lbafs_ExtSmart = json_create_object();
+ json_print_smart_log(lbafs_ExtSmart, &ExtdSMARTInfo);
+
+ json_object_add_value_array(root, "SMART-Attributes", lbafs);
+ json_array_add_value_object(lbafs, lbafs_ExtSmart);
+ }
+
+ /**
+ * Next get Log Page 0xCF
+ */
+
+ err = nvme_get_log_simple(dev_fd(dev), 0xCF, sizeof(logPageCF), &logPageCF);
+ if (!err) {
+ if (strcmp(cfg.output_format, "json")) {
+ print_smart_log_CF(&logPageCF);
+ } else {
+ lbafs_DramSmart = json_create_object();
+ json_print_smart_log_CF(lbafs_DramSmart, &logPageCF);
+ json_array_add_value_object(lbafs, lbafs_DramSmart);
+ json_print_object(root, NULL);
+ }
+ } else if (!strcmp(cfg.output_format, "json")) {
+ json_print_object(root, NULL);
+ json_free_object(root);
+ }
+ } else if (err > 0)
+ nvme_show_status(err);
+ } else {
+ err = nvme_get_log_simple(dev_fd(dev), 0xC0, sizeof(ehExtSmart), &ehExtSmart);
+
+ if (!err) {
+ if (strcmp(cfg.output_format, "json")) {
+ print_stx_smart_log_C0(&ehExtSmart);
+
+ } else {
+ lbafs_ExtSmart = json_create_object();
+ json_print_stx_smart_log_C0(lbafs_ExtSmart, &ehExtSmart);
+
+ json_object_add_value_array(root, "SMART-Attributes", lbafs);
+ json_array_add_value_object(lbafs, lbafs_ExtSmart);
+
+ json_print_object(root, NULL);
+ json_free_object(root);
+ }
+ }
+
+ if (err > 0)
+ nvme_show_status(err);
+ }
+
+ err = nvme_get_log_simple(dev_fd(dev), 0xC4,
+ sizeof(ExtdSMARTInfo), &ExtdSMARTInfo);
+ if (!err) {
+ if (strcmp(cfg.output_format, "json")) {
printf("%-39s %-15s %-19s \n", "Description", "Ext-Smart-Id", "Ext-Smart-Value");
- for(index=0; index<80; index++)
+ for (index = 0; index < 80; index++)
printf("-");
printf("\n");
- for(index = 0; index < NUMBER_EXTENDED_SMART_ATTRIBUTES; index++)
+ for (index = 0; index < NUMBER_EXTENDED_SMART_ATTRIBUTES; index++)
print_smart_log(ExtdSMARTInfo.Version, ExtdSMARTInfo.vendorData[index], index == (NUMBER_EXTENDED_SMART_ATTRIBUTES - 1));
} else {
@@ -767,11 +1094,10 @@ static int vs_smart_log(int argc, char **argv, struct command *cmd, struct plugi
* Next get Log Page 0xCF
*/
- err = nvme_get_log_simple(fd, 0xCF, sizeof(logPageCF), &logPageCF);
+ err = nvme_get_log_simple(dev_fd(dev), 0xCF,
+ sizeof(logPageCF), &logPageCF);
if (!err) {
- if(strcmp(cfg.output_format,"json")) {
- /*printf("Seagate DRAM Supercap SMART Attributes :\n");*/
-
+ if (strcmp(cfg.output_format, "json")) {
print_smart_log_CF(&logPageCF);
} else {
lbafs_DramSmart = json_create_object();
@@ -784,7 +1110,8 @@ static int vs_smart_log(int argc, char **argv, struct command *cmd, struct plugi
} else if (err > 0)
nvme_show_status(err);
- close(fd);
+ dev_close(dev);
+
return err;
}
@@ -794,7 +1121,7 @@ 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)
+ __u32 MaxSocTemp, __u32 cf_err, __u32 scCurrentTemp, __u32 scMaxTem)
{
struct json_object *root;
root = json_create_object();
@@ -804,28 +1131,27 @@ static void json_temp_stats(__u32 temperature, __u32 PcbTemp, __u32 SocTemp, __u
json_object_add_value_int(root, "Current SOC temperature", SocTemp);
json_object_add_value_int(root, "Highest temperature", maxTemperature);
json_object_add_value_int(root, "Max SOC temperature", MaxSocTemp);
- if(!cf_err) {
+ if (!cf_err) {
json_object_add_value_int(root, "SuperCap Current temperature", scCurrentTemp);
json_object_add_value_int(root, "SuperCap Max temperature", scMaxTem);
}
json_print_object(root, NULL);
- printf("\n");
-
}
+
static int temp_stats(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
struct nvme_smart_log smart_log;
EXTENDED_SMART_INFO_T ExtdSMARTInfo;
vendor_log_page_CF logPageCF;
- int fd;
int err, cf_err;
int index;
const char *desc = "Retrieve Seagate Temperature Stats information for the given device ";
const char *output_format = "output in binary format";
unsigned int temperature = 0, PcbTemp = 0, SocTemp = 0, scCurrentTemp = 0, scMaxTemp = 0;
unsigned long long maxTemperature = 0, MaxSocTemp = 0;
+ struct nvme_dev *dev;
struct config {
char *output_format;
};
@@ -839,16 +1165,16 @@ static int temp_stats(int argc, char **argv, struct command *cmd, struct plugin
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0) {
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err) {
printf ("\nDevice not found \n");;
return -1;
}
- if(strcmp(cfg.output_format,"json"))
+ if (strcmp(cfg.output_format, "json"))
printf("Seagate Temperature Stats Information :\n");
/*STEP-1 : Get Current Temperature from SMART */
- err = nvme_get_log_smart(fd, 0xffffffff, false, &smart_log);
+ err = nvme_get_log_smart(dev_fd(dev), 0xffffffff, false, &smart_log);
if (!err) {
temperature = ((smart_log.temperature[1] << 8) | smart_log.temperature[0]);
temperature = temperature ? temperature - 273 : 0;
@@ -856,7 +1182,7 @@ static int temp_stats(int argc, char **argv, struct command *cmd, struct plugin
PcbTemp = PcbTemp ? PcbTemp - 273 : 0;
SocTemp = le16_to_cpu(smart_log.temp_sensor[1]);
SocTemp = SocTemp ? SocTemp - 273 : 0;
- if (strcmp(cfg.output_format,"json")) {
+ if (strcmp(cfg.output_format, "json")) {
printf("%-20s : %u C\n", "Current Temperature", temperature);
printf("%-20s : %u C\n", "Current PCB Temperature", PcbTemp);
printf("%-20s : %u C\n", "Current SOC Temperature", SocTemp);
@@ -864,30 +1190,33 @@ 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(fd, 0xC4, sizeof(ExtdSMARTInfo), &ExtdSMARTInfo);
+ err = nvme_get_log_simple(dev_fd(dev), 0xC4,
+ sizeof(ExtdSMARTInfo), &ExtdSMARTInfo);
if (!err) {
- for(index = 0; index < NUMBER_EXTENDED_SMART_ATTRIBUTES; index++) {
+ for (index = 0; index < NUMBER_EXTENDED_SMART_ATTRIBUTES; index++) {
if (ExtdSMARTInfo.vendorData[index].AttributeNumber == VS_ATTR_ID_MAX_LIFE_TEMPERATURE) {
maxTemperature = smart_attribute_vs(ExtdSMARTInfo.Version, ExtdSMARTInfo.vendorData[index]);
maxTemperature = maxTemperature ? maxTemperature - 273 : 0;
- if (strcmp(cfg.output_format,"json"))
+ if (strcmp(cfg.output_format, "json"))
printf("%-20s : %d C\n", "Highest Temperature", (unsigned int)maxTemperature);
}
if (ExtdSMARTInfo.vendorData[index].AttributeNumber == VS_ATTR_ID_MAX_SOC_LIFE_TEMPERATURE) {
MaxSocTemp = smart_attribute_vs(ExtdSMARTInfo.Version, ExtdSMARTInfo.vendorData[index]);
MaxSocTemp = MaxSocTemp ? MaxSocTemp - 273 : 0;
- if (strcmp(cfg.output_format,"json"))
+ if (strcmp(cfg.output_format, "json"))
printf("%-20s : %d C\n", "Max SOC Temperature", (unsigned int)MaxSocTemp);
}
}
+ } else {
+ if (err > 0)
+ nvme_show_status(err);
}
- else if (err > 0)
- nvme_show_status(err);
- cf_err = nvme_get_log_simple(fd, 0xCF, sizeof(ExtdSMARTInfo), &logPageCF);
+ cf_err = nvme_get_log_simple(dev_fd(dev), 0xCF,
+ sizeof(ExtdSMARTInfo), &logPageCF);
- if(!cf_err) {
+ if (!cf_err) {
scCurrentTemp = logPageCF.AttrCF.SuperCapCurrentTemperature;
scCurrentTemp = scCurrentTemp ? scCurrentTemp - 273 : 0;
printf("%-20s : %d C\n", "Super-cap Current Temperature", scCurrentTemp);
@@ -897,10 +1226,10 @@ static int temp_stats(int argc, char **argv, struct command *cmd, struct plugin
printf("%-20s : %d C\n", "Super-cap Max Temperature", scMaxTemp);
}
- if(!strcmp(cfg.output_format,"json"))
+ if (!strcmp(cfg.output_format, "json"))
json_temp_stats(temperature, PcbTemp, SocTemp, maxTemperature, MaxSocTemp, cf_err, scCurrentTemp, scMaxTemp);
- close(fd);
+ dev_close(dev);
return err;
}
/* EOF Temperature Stats information */
@@ -987,13 +1316,12 @@ static void json_vs_pcie_error_log(pcie_error_log_page pcieErrorLog)
json_object_add_value_int(root, "Cpl TLP Poisoned Error Count", pcieErrorLog.CplTlpPoisonedErrCnt);
json_object_add_value_int(root, "Request Completion Abort Error Count", pcieErrorLog.ReqCAErrCnt);
json_print_object(root, NULL);
- printf("\n");
}
static int vs_pcie_error_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
pcie_error_log_page pcieErrorLog;
- int fd;
+ struct nvme_dev *dev;
const char *desc = "Retrieve Seagate PCIe error counters for the given device ";
const char *output_format = "output in binary format";
@@ -1011,18 +1339,19 @@ static int vs_pcie_error_log(int argc, char **argv, struct command *cmd, struct
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0) {
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err) {
printf ("\nDevice not found \n");;
return -1;
}
- if(strcmp(cfg.output_format,"json"))
+ if (strcmp(cfg.output_format, "json"))
printf("Seagate PCIe error counters Information :\n");
- err = nvme_get_log_simple(fd, 0xCB, sizeof(pcieErrorLog), &pcieErrorLog);
+ err = nvme_get_log_simple(dev_fd(dev), 0xCB,
+ sizeof(pcieErrorLog), &pcieErrorLog);
if (!err) {
- if(strcmp(cfg.output_format,"json")) {
+ if (strcmp(cfg.output_format, "json")) {
print_vs_pcie_error_log(pcieErrorLog);
} else
json_vs_pcie_error_log(pcieErrorLog);
@@ -1030,17 +1359,233 @@ static int vs_pcie_error_log(int argc, char **argv, struct command *cmd, struct
} else if (err > 0)
nvme_show_status(err);
- close(fd);
+ dev_close(dev);
return err;
}
/* EOF PCIE error-log information */
+
+/***************************************
+ * FW Activation History log
+ ***************************************/
+static void print_stx_vs_fw_activate_history(stx_fw_activ_history_log_page fwActivHis)
+{
+ __u32 i;
+ char prev_fw[9] = {0};
+ char new_fw[9] = {0};
+ char buf[80];
+
+ if (fwActivHis.numValidFwActHisEnt > 0) {
+ printf("\n\nSeagate FW Activation Histry :\n");
+ printf("%-9s %-21s %-7s %-13s %-9s %-5s %-15s %-9s\n", "Counter ", " Timestamp ", " PCC ", "Previous FW ", "New FW ", "Slot", "Commit Action", "Result");
+
+ for (i = 0; i < fwActivHis.numValidFwActHisEnt; i++) {
+
+ printf(" %-4d ", fwActivHis.fwActHisEnt[i].fwActivCnt);
+
+ time_t t = fwActivHis.fwActHisEnt[i].timeStamp / 1000;
+ struct tm ts;
+ ts = *localtime(&t);
+ strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &ts);
+ printf(" %-20s ", buf);
+ printf("%-5" PRId64 " ",
+ (uint64_t)fwActivHis.fwActHisEnt[i].powCycleCnt);
+
+ memset(prev_fw, 0, sizeof(prev_fw));
+ memcpy(prev_fw, fwActivHis.fwActHisEnt[i].previousFW, sizeof(fwActivHis.fwActHisEnt[i].previousFW));
+ printf("%-8s ", prev_fw);
+
+ memset(new_fw, 0, sizeof(new_fw));
+ memcpy(new_fw, fwActivHis.fwActHisEnt[i].newFW, sizeof(fwActivHis.fwActHisEnt[i].newFW));
+ printf("%-8s ", new_fw);
+
+ printf(" %-2d ", fwActivHis.fwActHisEnt[i].slotNum);
+ printf(" 0x%02x ", fwActivHis.fwActHisEnt[i].commitActionType);
+ printf(" 0x%02x \n", fwActivHis.fwActHisEnt[i].result);
+ }
+ } else {
+ printf("%s\n", "Do not have valid FW Activation History");
+ }
+}
+
+static void json_stx_vs_fw_activate_history(stx_fw_activ_history_log_page fwActivHis)
+{
+ struct json_object *root;
+ root = json_create_object();
+ __u32 i;
+
+ char buf[80];
+
+ struct json_object *historyLogPage;
+ historyLogPage = json_create_array();
+ json_object_add_value_array(root, "Seagate FW Activation History", historyLogPage);
+
+ if (fwActivHis.numValidFwActHisEnt > 0) {
+ for (i = 0; i < fwActivHis.numValidFwActHisEnt; i++) {
+ struct json_object *lbaf = json_create_object();
+ char prev_fw[8] = { 0 };
+ char new_fw[8] = { 0 };
+
+ json_object_add_value_int(lbaf, "Counter", fwActivHis.fwActHisEnt[i].fwActivCnt);
+
+ time_t t = fwActivHis.fwActHisEnt[i].timeStamp / 1000;
+ struct tm ts;
+ ts = *localtime(&t);
+ strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &ts);
+ printf(" %-20s ", buf);
+ json_object_add_value_string(lbaf, "Timestamp", buf);
+
+ json_object_add_value_int(lbaf, "PCC", fwActivHis.fwActHisEnt[i].powCycleCnt);
+ sprintf(prev_fw, "%s", fwActivHis.fwActHisEnt[i].previousFW);
+ json_object_add_value_string(lbaf, "Previous_FW", prev_fw);
+
+ sprintf(new_fw, "%s", fwActivHis.fwActHisEnt[i].newFW);
+ json_object_add_value_string(lbaf, "New_FW", new_fw);
+
+ json_object_add_value_int(lbaf, "Slot", fwActivHis.fwActHisEnt[i].slotNum);
+ json_object_add_value_int(lbaf, "Commit_Action", fwActivHis.fwActHisEnt[i].commitActionType);
+ json_object_add_value_int(lbaf, "Result", fwActivHis.fwActHisEnt[i].result);
+
+ json_array_add_value_object(historyLogPage, lbaf);
+ }
+ } else {
+ printf("%s\n", "Do not have valid FW Activation History");
+ }
+
+ json_print_object(root, NULL);
+ json_free_object(root);
+}
+
+static int stx_vs_fw_activate_history(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+{
+ stx_fw_activ_history_log_page fwActivHis;
+ struct nvme_dev *dev;
+
+ const char *desc = "Retrieve FW Activate History for Seagate device ";
+ const char *output_format = "output in binary format";
+ int err;
+ struct config {
+ char *output_format;
+ };
+
+ struct config cfg = {
+ .output_format = "normal",
+ };
+
+ OPT_ARGS(opts) = {
+ OPT_FMT("output-format", 'o', &cfg.output_format, output_format),
+ OPT_END()
+ };
+
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err < 0) {
+ printf ("\nDevice not found \n");;
+ return -1;
+ }
+
+ if (strcmp(cfg.output_format, "json"))
+ printf("Seagate FW Activation Histry Information :\n");
+
+ err = nvme_get_log_simple(dev_fd(dev), 0xC2, sizeof(fwActivHis), &fwActivHis);
+ if (!err) {
+ if (strcmp(cfg.output_format, "json")) {
+ print_stx_vs_fw_activate_history(fwActivHis);
+ } else
+ json_stx_vs_fw_activate_history(fwActivHis);
+
+ } else if (err > 0)
+ 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)
+{
+ 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;
+ struct nvme_id_ctrl ctrl;
+ char modelNo[40];
+ __u32 result;
+
+ struct config {
+ bool save;
+ };
+
+ struct config cfg = {
+ .save = 0,
+ };
+
+ OPT_ARGS(opts) = {
+ OPT_FLAG("save", 's', &cfg.save, save),
+ OPT_END()
+ };
+
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err < 0) {
+ printf ("\nDevice not found \n");
+ return -1;
+ }
+
+ err = nvme_identify_ctrl(dev_fd(dev), &ctrl);
+ if (!err) {
+ memcpy(modelNo, ctrl.mn, sizeof(modelNo));
+ } else {
+ nvme_show_status(err);
+ return err;
+ }
+
+ if (stx_is_jag_pan(modelNo) == 0) {
+ 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__);
+ }
+
+ if (err < 0) {
+ perror("set-feature");
+ return errno;
+ }
+
+ dev_close(dev);
+ return err;
+}
+
+
static int vs_clr_pcie_correctable_errs(int argc, char **argv, struct command *cmd, 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";
- int err, fd;
+
+ struct nvme_id_ctrl ctrl;
+ char modelNo[40];
+
+ struct nvme_dev *dev;
+
__u32 result;
+ int err;
struct config {
bool save;
@@ -1055,21 +1600,53 @@ static int vs_clr_pcie_correctable_errs(int argc, char **argv, struct command *c
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0) {
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err) {
printf ("\nDevice not found \n");;
return -1;
}
- err = nvme_set_features_simple(fd, 0xE1, 0, 0xCB, cfg.save, &result);
+
+ err = nvme_identify_ctrl(dev_fd(dev), &ctrl);
+ if (!err) {
+ memcpy(modelNo, ctrl.mn, sizeof(modelNo));
+ } else {
+ nvme_show_status(err);
+ return err;
+ }
+
+ if (stx_is_jag_pan(modelNo) == 0) {
+ err = nvme_set_features_simple(dev_fd(dev), 0xE1, 0, 0xCB, cfg.save, &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);
+ 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);
if (err < 0) {
perror("set-feature");
+ return errno;
}
- close(fd);
+ dev_close(dev);
return err;
-
}
static int get_host_tele(int argc, char **argv, struct command *cmd, struct plugin *plugin)
@@ -1081,11 +1658,12 @@ static int get_host_tele(int argc, char **argv, struct command *cmd, struct plug
"state of the controller at the time the command is processed. " \
"0 - controller shall not update the Telemetry Host Initiated Data.";
const char *raw = "output in raw format";
- int err, fd, dump_fd;
struct nvme_temetry_log_hdr tele_log;
- __le64 offset = 0;
int blkCnt, maxBlk = 0, blksToGet;
+ struct nvme_dev *dev;
unsigned char *log;
+ __le64 offset = 0;
+ int err, dump_fd;
struct config {
__u32 namespace_id;
@@ -1105,24 +1683,25 @@ static int get_host_tele(int argc, char **argv, struct command *cmd, struct plug
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ err = parse_and_open(&dev, 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(fd, false, cfg.log_id, cfg.namespace_id,
- sizeof(tele_log), (void *)(&tele_log));
+ err = nvme_get_nsid_log(dev_fd(dev), false, cfg.log_id,
+ cfg.namespace_id,
+ sizeof(tele_log), (void *)(&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",
- devicename, cfg.log_id,
- cfg.namespace_id);
+ dev->name, 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);
+ tele_log.tele_data_area1, tele_log.tele_data_area2, tele_log.tele_data_area3);
d((unsigned char *)(&tele_log), sizeof(tele_log), 16, 1);
} else
@@ -1134,13 +1713,13 @@ static int get_host_tele(int argc, char **argv, struct command *cmd, struct plug
blkCnt = 0;
- while(blkCnt < maxBlk) {
+ while (blkCnt < maxBlk) {
unsigned long long bytesToGet;
blksToGet = ((maxBlk - blkCnt) >= TELEMETRY_BLOCKS_TO_READ) ? TELEMETRY_BLOCKS_TO_READ : (maxBlk - blkCnt);
- if(blksToGet == 0) {
- close(fd);
+ if (blksToGet == 0) {
+ dev_close(dev);
return err;
}
@@ -1149,28 +1728,28 @@ 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");
- close(fd);
+ dev_close(dev);
return EINVAL;
}
memset(log, 0, bytesToGet);
struct nvme_get_log_args args = {
- .args_size = sizeof(args),
- .fd = fd,
- .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,
+ .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);
if (!err) {
@@ -1192,17 +1771,18 @@ static int get_host_tele(int argc, char **argv, struct command *cmd, struct plug
free(log);
}
- close(fd);
+ dev_close(dev);
return err;
}
static int get_ctrl_tele(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- const char *desc = "Capture the Telemetry Controller-Initiated Data in either " \
+ 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";
- int err, fd, dump_fd;
+ struct nvme_dev *dev;
+ int err, dump_fd;
struct nvme_temetry_log_hdr tele_log;
__le64 offset = 0;
__u16 log_id;
@@ -1224,24 +1804,24 @@ static int get_ctrl_tele(int argc, char **argv, struct command *cmd, struct plug
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
dump_fd = STDOUT_FILENO;
log_id = 0x08;
- err = nvme_get_nsid_log(fd, false, log_id, cfg.namespace_id,
- sizeof(tele_log), (void *)(&tele_log));
+ err = nvme_get_nsid_log(dev_fd(dev), false, log_id, cfg.namespace_id,
+ sizeof(tele_log), (void *)(&tele_log));
if (!err) {
maxBlk = tele_log.tele_data_area3;
offset += 512;
if (!cfg.raw_binary) {
printf("Device:%s namespace-id:%#x\n",
- devicename, cfg.namespace_id);
+ dev->name, 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);
+ tele_log.tele_data_area1, tele_log.tele_data_area2, tele_log.tele_data_area3);
d((unsigned char *)(&tele_log), sizeof(tele_log), 16, 1);
} else
@@ -1253,12 +1833,12 @@ static int get_ctrl_tele(int argc, char **argv, struct command *cmd, struct plug
blkCnt = 0;
- while(blkCnt < maxBlk) {
+ while (blkCnt < maxBlk) {
unsigned long long bytesToGet;
blksToGet = ((maxBlk - blkCnt) >= TELEMETRY_BLOCKS_TO_READ) ? TELEMETRY_BLOCKS_TO_READ : (maxBlk - blkCnt);
- if(blksToGet == 0)
+ if (blksToGet == 0)
return err;
bytesToGet = (unsigned long long)blksToGet * 512;
@@ -1272,21 +1852,21 @@ 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 = fd,
- .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,
+ .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);
if (!err) {
@@ -1308,21 +1888,14 @@ static int get_ctrl_tele(int argc, char **argv, struct command *cmd, struct plug
free(log);
}
- close(fd);
+ dev_close(dev);
return err;
}
void seaget_d_raw(unsigned char *buf, int len, int fd)
{
- /*********************
- int i;
- fflush(stdout);
- for (i = 0; i < len; i++)
- putchar(*(buf+i));
- *********************/
-
if (write(fd, (void *)buf, len) <= 0)
- printf("%s: Write Failed\n",__FUNCTION__);
+ printf("%s: Write Failed\n", __FUNCTION__);
}
@@ -1333,9 +1906,10 @@ static int vs_internal_log(int argc, char **argv, struct command *cmd, struct pl
const char *namespace_id = "desired namespace";
const char *file = "dump file";
- int err, fd, dump_fd;
+ struct nvme_dev *dev;
+ int err, dump_fd;
int flags = O_WRONLY | O_CREAT;
- int mode = S_IRUSR | S_IWUSR |S_IRGRP | S_IWGRP| S_IROTH;
+ int mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH;
struct nvme_temetry_log_hdr tele_log;
__le64 offset = 0;
__u16 log_id;
@@ -1358,31 +1932,27 @@ static int vs_internal_log(int argc, char **argv, struct command *cmd, struct pl
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
dump_fd = STDOUT_FILENO;
- if(strlen(cfg.file)) {
+ if (strlen(cfg.file)) {
dump_fd = open(cfg.file, flags, mode);
if (dump_fd < 0) {
perror(cfg.file);
- close(fd);
+ dev_close(dev);
return EINVAL;
}
}
log_id = 0x08;
- err = nvme_get_nsid_log(fd, false, log_id, cfg.namespace_id,
- sizeof(tele_log), (void *)(&tele_log));
+ err = nvme_get_nsid_log(dev_fd(dev), false, log_id, cfg.namespace_id,
+ sizeof(tele_log), (void *)(&tele_log));
if (!err) {
maxBlk = tele_log.tele_data_area3;
offset += 512;
- /*
- 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);
- */
seaget_d_raw((unsigned char *)(&tele_log), sizeof(tele_log), dump_fd);
} else if (err > 0)
nvme_show_status(err);
@@ -1391,12 +1961,12 @@ static int vs_internal_log(int argc, char **argv, struct command *cmd, struct pl
blkCnt = 0;
- while(blkCnt < maxBlk) {
+ while (blkCnt < maxBlk) {
unsigned long long bytesToGet;
blksToGet = ((maxBlk - blkCnt) >= TELEMETRY_BLOCKS_TO_READ) ? TELEMETRY_BLOCKS_TO_READ : (maxBlk - blkCnt);
- if(blksToGet == 0) {
+ if (blksToGet == 0) {
goto out;
}
@@ -1412,21 +1982,21 @@ 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 = fd,
- .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,
+ .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);
if (!err) {
@@ -1444,20 +2014,29 @@ static int vs_internal_log(int argc, char **argv, struct command *cmd, struct pl
free(log);
}
out:
- if(strlen(cfg.file))
+ if (strlen(cfg.file))
close(dump_fd);
- close(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 *cmd, struct plugin *plugin)
{
printf("Seagate-Plugin version : %d.%d \n",
- SEAGATE_PLUGIN_VERSION_MAJOR,
- SEAGATE_PLUGIN_VERSION_MINOR);
+ SEAGATE_PLUGIN_VERSION_MAJOR,
+ SEAGATE_PLUGIN_VERSION_MINOR);
return 0;
}
/*EOF SEAGATE-PLUGIN Version */
+
+/*OCP SEAGATE-PLUGIN Version */
+static int stx_ocp_plugin_version(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+{
+ printf("Seagate-OCP-Plugin version : %d.%d \n",
+ SEAGATE_OCP_PLUGIN_VERSION_MAJOR,
+ SEAGATE_OCP_PLUGIN_VERSION_MINOR);
+ return 0;
+}
+/*EOF OCP SEAGATE-PLUGIN Version */
diff --git a/plugins/seagate/seagate-nvme.h b/plugins/seagate/seagate-nvme.h
index 6df1331..99f6327 100644
--- a/plugins/seagate/seagate-nvme.h
+++ b/plugins/seagate/seagate-nvme.h
@@ -18,6 +18,8 @@
*
* \file seagate-nvme.h
* \brief This file defines the functions and macros to make building a nvme-cli seagate plug-in.
+ *
+ * Author: Debabrata Bardhan <debabrata.bardhan@seagate.com>
*/
#undef CMD_INC_FILE
@@ -30,15 +32,18 @@
PLUGIN(NAME("seagate", "Seagate vendor specific extensions", NVME_VERSION),
COMMAND_LIST(
- ENTRY("vs-temperature-stats", "Retrieve Seagate temperature statistics ", temp_stats)
- ENTRY("vs-log-page-sup", "Retrieve Seagate Supported Log-pages Information ", log_pages_supp)
- ENTRY("vs-smart-add-log", "Retrieve Seagate extended-SMART Information ", vs_smart_log)
- ENTRY("vs-pcie-stats", "Retrieve Seagate PCIe error statistics ", vs_pcie_error_log)
- ENTRY("clear-pcie-correctable-errors", "Clear Seagate PCIe error statistics ", vs_clr_pcie_correctable_errs)
- ENTRY("get-host-tele", "Retrieve Seagate Host-Initiated Telemetry ", get_host_tele)
- ENTRY("get-ctrl-tele", "Retrieve Seagate Controller-Initiated Telemetry ", get_ctrl_tele)
- ENTRY("vs-internal-log", "Retrieve Seagate Controller-Initiated Telemetry in binary format", vs_internal_log)
- ENTRY("plugin-version", "Shows Seagate plugin's version information ", seagate_plugin_version)
+ ENTRY("vs-temperature-stats", "Retrieve Seagate temperature statistics ", temp_stats)
+ ENTRY("vs-log-page-sup", "Retrieve Seagate Supported Log-pages Information ", log_pages_supp)
+ ENTRY("vs-smart-add-log", "Retrieve Seagate extended-SMART Information ", vs_smart_log)
+ ENTRY("vs-pcie-stats", "Retrieve Seagate PCIe error statistics ", vs_pcie_error_log)
+ ENTRY("clear-pcie-correctable-errors", "Clear Seagate PCIe error statistics ", vs_clr_pcie_correctable_errs)
+ ENTRY("get-host-tele", "Retrieve Seagate Host-Initiated Telemetry ", get_host_tele)
+ ENTRY("get-ctrl-tele", "Retrieve Seagate Controller-Initiated Telemetry ", get_ctrl_tele)
+ ENTRY("vs-internal-log", "Retrieve Seagate Controller-Initiated Telemetry in binary format", vs_internal_log)
+ ENTRY("vs-fw-activate-history", "Retrieve the Firmware Activation History", stx_vs_fw_activate_history)
+ ENTRY("clear-fw-activate-history", "Clear Firmware Activation History", clear_fw_activate_history)
+ ENTRY("plugin-version", "Shows Seagate plugin's version information ", seagate_plugin_version)
+ ENTRY("cloud-SSD-plugin-version", "Shows OCP Seagate plugin's version information ", stx_ocp_plugin_version)
)
);
diff --git a/plugins/shannon/shannon-nvme.c b/plugins/shannon/shannon-nvme.c
index 220638f..424b3f7 100644
--- a/plugins/shannon/shannon-nvme.c
+++ b/plugins/shannon/shannon-nvme.c
@@ -117,15 +117,16 @@ static void show_shannon_smart_log(struct nvme_shannon_smart_log *smart,
static int get_additional_smart_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
struct nvme_shannon_smart_log smart_log;
- int err, fd;
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;
struct config {
__u32 namespace_id;
bool raw_binary;
};
+ int err;
struct config cfg = {
.namespace_id = NVME_NSID_ALL,
@@ -137,20 +138,21 @@ static int get_additional_smart_log(int argc, char **argv, struct command *cmd,
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
- err = nvme_get_nsid_log(fd, false, 0xca, cfg.namespace_id,
- sizeof(smart_log), &smart_log);
+ err = parse_and_open(&dev, 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);
if (!err) {
if (!cfg.raw_binary)
- show_shannon_smart_log(&smart_log, cfg.namespace_id, devicename);
+ show_shannon_smart_log(&smart_log, cfg.namespace_id,
+ dev->name);
else
d_raw((unsigned char *)&smart_log, sizeof(smart_log));
}
else if (err > 0)
nvme_show_status(err);
- close(fd);
+ dev_close(dev);
return err;
}
@@ -174,9 +176,10 @@ 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";
- int err, fd;
- __u32 result;
+ struct nvme_dev *dev;
void *buf = NULL;
+ __u32 result;
+ int err;
struct config {
__u32 namespace_id;
@@ -207,24 +210,24 @@ static int get_additional_feature(int argc, char **argv, struct command *cmd, st
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
if (cfg.sel > 7) {
fprintf(stderr, "invalid 'select' param:%d\n", cfg.sel);
- close(fd);
+ dev_close(dev);
return EINVAL;
}
if (!cfg.feature_id) {
fprintf(stderr, "feature-id required param\n");
- close(fd);
+ dev_close(dev);
return EINVAL;
}
if (cfg.data_len) {
if (posix_memalign(&buf, getpagesize(), cfg.data_len))
{
- close(fd);
+ dev_close(dev);
exit(ENOMEM);
}
memset(buf, 0, cfg.data_len);
@@ -232,7 +235,7 @@ static int get_additional_feature(int argc, char **argv, struct command *cmd, st
struct nvme_get_features_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.fid = cfg.feature_id,
.nsid = cfg.namespace_id,
.sel = cfg.sel,
@@ -286,10 +289,11 @@ 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";
- int err, fd;
- __u32 result;
- void *buf = NULL;
int ffd = STDIN_FILENO;
+ struct nvme_dev *dev;
+ void *buf = NULL;
+ __u32 result;
+ int err;
struct config {
char *file;
@@ -319,20 +323,20 @@ static int set_additional_feature(int argc, char **argv, struct command *cmd, st
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
if (!cfg.feature_id) {
fprintf(stderr, "feature-id required param\n");
- close(fd);
+ 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");
- close(fd);
+ dev_close(dev);
return ENOMEM;
}
memset(buf, 0, cfg.data_len);
@@ -357,7 +361,7 @@ static int set_additional_feature(int argc, char **argv, struct command *cmd, st
struct nvme_set_features_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.fid = cfg.feature_id,
.nsid = cfg.namespace_id,
.cdw11 = cfg.value,
diff --git a/plugins/solidigm/meson.build b/plugins/solidigm/meson.build
index fb0f6a9..bca13bb 100644
--- a/plugins/solidigm/meson.build
+++ b/plugins/solidigm/meson.build
@@ -2,4 +2,6 @@ sources += [
'plugins/solidigm/solidigm-smart.c',
'plugins/solidigm/solidigm-garbage-collection.c',
'plugins/solidigm/solidigm-latency-tracking.c',
+ 'plugins/solidigm/solidigm-telemetry.c',
]
+subdir('solidigm-telemetry')
diff --git a/plugins/solidigm/solidigm-garbage-collection.c b/plugins/solidigm/solidigm-garbage-collection.c
index 415722b..8e2eccc 100644
--- a/plugins/solidigm/solidigm-garbage-collection.c
+++ b/plugins/solidigm/solidigm-garbage-collection.c
@@ -56,13 +56,15 @@ static void vu_gc_log_show(garbage_control_collection_log_t *payload, const char
for (int i = 0; i < VU_GC_MAX_ITEMS; i++) {
gc_item_t item = payload->item[i];
- printf("%-13lu %d\n",le64_to_cpu(item.timestamp), le32_to_cpu(item.timer_type));
+ printf("%-13" PRIu64 " %d\n", le64_to_cpu(item.timestamp), le32_to_cpu(item.timer_type));
}
}
int solidigm_get_garbage_collection_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
const char *desc = "Get and parse Solidigm vendor specific garbage collection event log.";
+ struct nvme_dev *dev;
+ int err;
struct config {
char *output_format;
@@ -77,35 +79,37 @@ int solidigm_get_garbage_collection_log(int argc, char **argv, struct command *c
OPT_END()
};
- int fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0) {
- return fd;
- }
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
enum nvme_print_flags flags = validate_output_format(cfg.output_format);
if (flags == -EINVAL) {
fprintf(stderr, "Invalid output format '%s'\n", cfg.output_format);
- close(fd);
- return flags;
+ dev_close(dev);
+ return EINVAL;
}
garbage_control_collection_log_t gc_log;
const int solidigm_vu_gc_log_id = 0xfd;
- int err = nvme_get_log_simple(fd, solidigm_vu_gc_log_id, sizeof(gc_log), &gc_log);
+ err = nvme_get_log_simple(dev_fd(dev), solidigm_vu_gc_log_id,
+ sizeof(gc_log), &gc_log);
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, devicename);
+ vu_gc_log_show_json(&gc_log, dev->name);
} else {
- vu_gc_log_show(&gc_log, devicename);
+ vu_gc_log_show(&gc_log, dev->name);
}
}
else if (err > 0) {
nvme_show_status(err);
}
-
- close(fd);
+
+ /* 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.c b/plugins/solidigm/solidigm-latency-tracking.c
index 0bfd611..1013ae8 100644
--- a/plugins/solidigm/solidigm-latency-tracking.c
+++ b/plugins/solidigm/solidigm-latency-tracking.c
@@ -216,7 +216,7 @@ static void latency_tracker_pre_parse(struct latency_tracker *lt)
printf("Major Revision: %u\nMinor Revision: %u\n",
le16_to_cpu(lt->stats.version_major), le16_to_cpu(lt->stats.version_minor));
if (lt->has_average_latency_field) {
- printf("Average Latency: %lu\n", le64_to_cpu(lt->stats.average_latency));
+ printf("Average Latency: %" PRIu64 "\n", le64_to_cpu(lt->stats.average_latency));
}
print_dash_separator();
printf("%-12s%-12s%-12s%-20s\n", "Bucket", "Start", "End", "Value");
@@ -385,6 +385,7 @@ int solidigm_get_latency_tracking_log(int argc, char **argv, struct command *cmd
struct plugin *plugin)
{
const char *desc = "Get and Parse Solidigm Latency Tracking Statistics log.";
+ struct nvme_dev *dev;
__u32 enabled;
int err;
@@ -407,43 +408,45 @@ int solidigm_get_latency_tracking_log(int argc, char **argv, struct command *cmd
OPT_END()
};
- lt.fd = parse_and_open(argc, argv, desc, opts);
- if (lt.fd < 0)
- return lt.fd;
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
+
+ lt.fd = dev_fd(dev);
lt.print_flags = validate_output_format(lt.cfg.output_format);
if (lt.print_flags == -EINVAL) {
fprintf(stderr, "Invalid output format '%s'\n", lt.cfg.output_format);
- close(lt.fd);
+ dev_close(dev);
return EINVAL;
}
if (lt.cfg.type > 0xf) {
fprintf(stderr, "Invalid Log type value '%d'\n", lt.cfg.type);
- close(lt.fd);
+ 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");
- close(lt.fd);
+ dev_close(dev);
return EINVAL;
}
err = latency_tracking_enable(&lt);
if (err){
- close(lt.fd);
+ dev_close(dev);
return err;
}
err = latency_tracker_get_log(&lt);
if (err){
- close(lt.fd);
+ dev_close(dev);
return err;
}
if ((lt.cfg.read || lt.cfg.write || lt.cfg.enable || lt.cfg.disable)) {
- close(lt.fd);
+ dev_close(dev);
return 0;
}
@@ -465,6 +468,8 @@ int solidigm_get_latency_tracking_log(int argc, char **argv, struct command *cmd
} else {
fprintf(stderr, "Could not read feature id 0xE2.\n");
}
- close(lt.fd);
+ /* Redundant close() to make static code analysis happy */
+ close(dev->direct.fd);
+ dev_close(dev);
return err;
}
diff --git a/plugins/solidigm/solidigm-nvme.c b/plugins/solidigm/solidigm-nvme.c
index 3eb3cc9..684648a 100644
--- a/plugins/solidigm/solidigm-nvme.c
+++ b/plugins/solidigm/solidigm-nvme.c
@@ -13,6 +13,7 @@
#include "solidigm-smart.h"
#include "solidigm-garbage-collection.h"
#include "solidigm-latency-tracking.h"
+#include "solidigm-telemetry.h"
static int get_additional_smart_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
@@ -27,4 +28,9 @@ static int get_garbage_collection_log(int argc, char **argv, struct command *cmd
static int get_latency_tracking_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
return solidigm_get_latency_tracking_log(argc, argv, cmd, plugin);
+}
+
+static int get_telemetry_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
+{
+ return solidigm_get_telemetry_log(argc, argv, cmd, plugin);
} \ No newline at end of file
diff --git a/plugins/solidigm/solidigm-nvme.h b/plugins/solidigm/solidigm-nvme.h
index 9fc8b45..ed48400 100644
--- a/plugins/solidigm/solidigm-nvme.h
+++ b/plugins/solidigm/solidigm-nvme.h
@@ -13,13 +13,14 @@
#include "cmd.h"
-#define SOLIDIGM_PLUGIN_VERSION "0.4"
+#define SOLIDIGM_PLUGIN_VERSION "0.6"
PLUGIN(NAME("solidigm", "Solidigm vendor specific extensions", SOLIDIGM_PLUGIN_VERSION),
COMMAND_LIST(
ENTRY("smart-log-add", "Retrieve Solidigm SMART Log", get_additional_smart_log)
ENTRY("garbage-collect-log", "Retrieve Garbage Collection Log", get_garbage_collection_log)
ENTRY("latency-tracking-log", "Enable/Retrieve Latency tracking Log", get_latency_tracking_log)
+ ENTRY("parse-telemetry-log", "Parse Telemetry Log binary", get_telemetry_log)
)
);
diff --git a/plugins/solidigm/solidigm-smart.c b/plugins/solidigm/solidigm-smart.c
index 77a2210..77c26ac 100644
--- a/plugins/solidigm/solidigm-smart.c
+++ b/plugins/solidigm/solidigm-smart.c
@@ -10,8 +10,6 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
-#include <inttypes.h>
-#include <endian.h>
#include "common.h"
#include "nvme.h"
@@ -201,7 +199,8 @@ int solidigm_get_additional_smart_log(int argc, char **argv, struct command *cmd
const int solidigm_vu_smart_log_id = 0xCA;
vu_smart_log_t smart_log_payload;
enum nvme_print_flags flags;
- int fd, err;
+ struct nvme_dev *dev;
+ int err;
struct config {
__u32 namespace_id;
@@ -219,32 +218,36 @@ int solidigm_get_additional_smart_log(int argc, char **argv, struct command *cmd
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0) {
- return fd;
- }
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
flags = validate_output_format(cfg.output_format);
if (flags == -EINVAL) {
fprintf(stderr, "Invalid output format '%s'\n", cfg.output_format);
- close(fd);
+ dev_close(dev);
return flags;
}
- err = nvme_get_log_simple(fd, solidigm_vu_smart_log_id, sizeof(smart_log_payload), &smart_log_payload);
+ err = nvme_get_log_simple(dev_fd(dev), solidigm_vu_smart_log_id,
+ sizeof(smart_log_payload), &smart_log_payload);
if (!err) {
if (flags & JSON) {
- vu_smart_log_show_json(&smart_log_payload, cfg.namespace_id, devicename);
+ vu_smart_log_show_json(&smart_log_payload,
+ cfg.namespace_id, dev->name);
} 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, devicename);
+ vu_smart_log_show(&smart_log_payload, cfg.namespace_id,
+ dev->name);
}
} else if (err > 0) {
nvme_show_status(err);
}
- close(fd);
+ /* Redundant close() to make static code analysis happy */
+ close(dev->direct.fd);
+ dev_close(dev);
return err;
}
diff --git a/plugins/solidigm/solidigm-telemetry.c b/plugins/solidigm/solidigm-telemetry.c
new file mode 100644
index 0000000..84a4e2a
--- /dev/null
+++ b/plugins/solidigm/solidigm-telemetry.c
@@ -0,0 +1,183 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2022 Solidigm.
+ *
+ * Author: leonardo.da.cunha@solidigm.com
+ */
+
+#include <fcntl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "common.h"
+#include "nvme.h"
+#include "libnvme.h"
+#include "plugin.h"
+#include "nvme-print.h"
+#include "solidigm-telemetry.h"
+#include "solidigm-telemetry/telemetry-log.h"
+#include "solidigm-telemetry/cod.h"
+#include "solidigm-telemetry/header.h"
+#include "solidigm-telemetry/config.h"
+#include "solidigm-telemetry/data-area.h"
+
+static int read_file2buffer(char *file_name, char **buffer, size_t *length)
+{
+ FILE *fd = fopen(file_name, "rb");
+
+ if (!fd)
+ return errno;
+
+ fseek(fd, 0, SEEK_END);
+ size_t length_bytes = ftell(fd);
+
+ fseek(fd, 0, SEEK_SET);
+
+ *buffer = malloc(length_bytes);
+ if (!*buffer) {
+ fclose(fd);
+ return errno;
+ }
+ *length = fread(*buffer, 1, length_bytes, fd);
+ fclose(fd);
+ return 0;
+}
+
+struct config {
+ __u32 host_gen;
+ bool ctrl_init;
+ int data_area;
+ char *cfg_file;
+ bool is_input_file;
+};
+
+int solidigm_get_telemetry_log(int argc, char **argv, struct command *cmd, 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.";
+ const char *cgen = "Gather report generated by the controller.";
+ const char *dgen = "Pick which telemetry data area to report. Default is 3 to fetch areas 1-3. Valid options are 1, 2, 3, 4.";
+ const char *cfile = "JSON configuration file";
+ const char *sfile = "data source <device> is binary file containing log dump instead of block or character device";
+ struct nvme_dev *dev;
+
+ struct telemetry_log tl = {
+ .root = json_create_object(),
+ .log = NULL,
+ };
+
+ struct config cfg = {
+ .host_gen = 1,
+ .ctrl_init = false,
+ .data_area = 3,
+ .cfg_file = NULL,
+ .is_input_file = false,
+ };
+
+ OPT_ARGS(opts) = {
+ OPT_UINT("host-generate", 'g', &cfg.host_gen, hgen),
+ OPT_FLAG("controller-init", 'c', &cfg.ctrl_init, cgen),
+ OPT_UINT("data-area", 'd', &cfg.data_area, dgen),
+ OPT_FILE("config-file", 'j', &cfg.cfg_file, cfile),
+ OPT_FLAG("source-file", 's', &cfg.is_input_file, sfile),
+ OPT_END()
+ };
+
+ int err = argconfig_parse(argc, argv, desc, opts);
+
+ if (err)
+ goto ret;
+
+ if (cfg.is_input_file) {
+ if (optind >= argc) {
+ err = errno = EINVAL;
+ perror(argv[0]);
+ goto ret;
+ }
+ char *binary_file_name = argv[optind];
+
+ err = read_file2buffer(binary_file_name, (char **)&tl.log, &tl.log_size);
+ } else {
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ }
+ if (err)
+ goto ret;
+
+ if (cfg.host_gen > 1) {
+ SOLIDIGM_LOG_WARNING("Invalid host-generate value '%d'", cfg.host_gen);
+ err = EINVAL;
+ goto close_fd;
+ }
+
+ if (cfg.cfg_file) {
+ char *conf_str = 0;
+ size_t length = 0;
+
+ err = read_file2buffer(cfg.cfg_file, &conf_str, &length);
+ if (err) {
+ SOLIDIGM_LOG_WARNING("Failed to open JSON configuration file %s: %s!",
+ cfg.cfg_file, strerror(err));
+ goto close_fd;
+ }
+ json_tokener * jstok = json_tokener_new();
+
+ tl.configuration = json_tokener_parse_ex(jstok, conf_str, length);
+ if (jstok->err != json_tokener_success) {
+ SOLIDIGM_LOG_WARNING("Parsing error on JSON configuration file %s: %s (at offset %d)",
+ cfg.cfg_file,
+ json_tokener_error_desc(jstok->err),
+ jstok->char_offset);
+ json_tokener_free(jstok);
+ err = EINVAL;
+ goto close_fd;
+ }
+ json_tokener_free(jstok);
+ }
+
+ if (!cfg.is_input_file) {
+ if (cfg.ctrl_init)
+ err = nvme_get_ctrl_telemetry(dev_fd(dev), true,
+ &tl.log, cfg.data_area,
+ &tl.log_size);
+ else if (cfg.host_gen)
+ err = nvme_get_new_host_telemetry(dev_fd(dev), &tl.log,
+ cfg.data_area,
+ &tl.log_size);
+ else
+ err = nvme_get_host_telemetry(dev_fd(dev), &tl.log,
+ cfg.data_area,
+ &tl.log_size);
+
+ if (err < 0) {
+ SOLIDIGM_LOG_WARNING("get-telemetry-log: %s",
+ nvme_strerror(errno));
+ goto close_fd;
+ } else if (err > 0) {
+ nvme_show_status(err);
+ SOLIDIGM_LOG_WARNING("Failed to acquire telemetry log %d!", err);
+ goto close_fd;
+ }
+ }
+ solidigm_telemetry_log_header_parse(&tl);
+ if (cfg.cfg_file)
+ solidigm_telemetry_log_data_areas_parse(&tl, cfg.data_area);
+ else
+ solidigm_telemetry_log_cod_parse(&tl);
+
+ json_print_object(tl.root, NULL);
+ json_free_object(tl.root);
+ printf("\n");
+
+close_fd:
+ if (!cfg.is_input_file) {
+ /* Redundant close() to make static code analysis happy */
+ close(dev->direct.fd);
+ dev_close(dev);
+ }
+ret:
+ json_free_object(tl.configuration);
+ free(tl.log);
+ return err;
+}
diff --git a/plugins/solidigm/solidigm-telemetry.h b/plugins/solidigm/solidigm-telemetry.h
new file mode 100644
index 0000000..971ee2a
--- /dev/null
+++ b/plugins/solidigm/solidigm-telemetry.h
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2022 Solidigm.
+ *
+ * Author: leonardo.da.cunha@solidigm.com
+ */
+
+int solidigm_get_telemetry_log(int argc, char **argv, struct command *cmd, struct plugin *plugin);
diff --git a/plugins/solidigm/solidigm-telemetry/cod.c b/plugins/solidigm/solidigm-telemetry/cod.c
new file mode 100644
index 0000000..be5685b
--- /dev/null
+++ b/plugins/solidigm/solidigm-telemetry/cod.c
@@ -0,0 +1,194 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright (c) 2022 Solidigm.
+ *
+ * Author: leonardo.da.cunha@solidigm.com
+ */
+#include "common.h"
+#include "cod.h"
+
+const char *oemDataMapDesc[] = {
+ "Media Read Count", //Uid 0x00
+ "Host Read count", //Uid 0x01
+ "Media Write Count", //Uid 0x02
+ "Host Write Count", //Uid 0x03
+ "Device Model", // 0x04
+ "Serial Number", // 0x05
+ "Firmware Revision", // 0x06
+ "Drive Status", // 0x07
+ "Minimum Temperature", // 0x08
+ "Maximum Temperature", // 0x09
+ "Power Loss Protection Status", // 0x0a
+ "Lifetime Unsafe Shutdown Count", // 0x0b
+ "Lifetime Power Cycle Count", // 0x0c
+ "Minimum Read Latency", // 0x0d
+ "Maximum Read Latency", // 0x0e
+ "Average Read Latency", // 0x0f
+ "Minimum Write Latency", // 0x10
+ "Maximum Write Latency", // 0x11
+ "Average Write Latency", // 0x12
+ "Grown Defects Count", // 0x13
+ "DQS Recovery Count", // 0x14
+ "Program Fail Count", // 0x15
+ "Erase Fail Count", // 0x16
+ "Defrag Writes in Progress Count", // 0x17
+ "Total Defrag Writes Count", // 0x18
+ "Max Die Offline Number", // 0x19
+ "Current Die Offline Number", // 0x1A
+ "XOR Enable Status", // 0x1B
+ "Media Life Used", // 0x1C
+ "Uncorrectable Error Count", // 0x1D
+ "Current Wear Range Delta", // 0x1E
+ "Read Errors Corrected by XOR", // 0x1F
+ "Background Data Refresh", // 0x20
+ "Pmic Vin History Data 1 Min", // 0x21
+ "Pmic Vin History Data 1 Max", // 0x22
+ "Pmic Vin History Data 1 Avg", // 0x23
+ "Pmic Vin History Data 2 Min", // 0x24
+ "Pmic Vin History Data 2 Max", // 0x25
+ "Pmic Vin History Data 2 Avg", // 0x26
+ "Pmic Vin History Data Total Readings", // 0x27
+ "All Time Current Max Wear Level", // 0x28
+ "Media Wear Remaining", // 0x29
+ "Total Non-Defrag Writes", // 0x2A
+ "Number of sectors relocated in reaction to an error" //Uid 0x2B = 43
+};
+
+static const char * getOemDataMapDescription(__u32 id)
+{
+ if (id < (sizeof(oemDataMapDesc) / sizeof(oemDataMapDesc[0]))) {
+ return oemDataMapDesc[id];
+ }
+ return "unknown";
+}
+
+#define OEMSIGNATURE 0x504D4443
+
+#pragma pack(push, cod, 1)
+struct cod_header
+{
+ uint32_t versionMajor;
+ uint32_t versionMinor;
+ uint32_t Signature; //!Fixed signature value (0x504D4443) for identification and validation
+ uint32_t MapSizeInBytes; //!Total size of the map data structure in bytes
+ uint32_t EntryCount; //!Total number of entries in the entry list
+ uint8_t Reserved[12];
+};
+
+struct cod_item
+{
+ uint32_t DataFieldMapUid; //!The data field unique identifier value
+ uint32_t reserved1 : 8;
+ uint32_t dataFieldType : 8;
+ uint32_t issigned : 1;
+ uint32_t bigEndian : 1;
+ uint32_t dataInvalid : 1;
+ uint32_t reserved2 : 13;
+ uint32_t DataFieldSizeInBytes;
+ uint8_t Reserved1[4];
+ uint64_t DataFieldOffset;
+ uint8_t Reserved2[8];
+};
+
+struct cod_map
+{
+ struct cod_header header;
+ struct cod_item items[];
+};
+
+#pragma pack(pop, cod)
+
+void solidigm_telemetry_log_cod_parse(struct telemetry_log *tl)
+{
+ enum cod_field_type
+ {
+ INTEGER,
+ FLOAT,
+ STRING,
+ TWO_BYTE_ASCII,
+ FOUR_BYTE_ASCII,
+
+ UNKNOWN = 0xFF,
+ };
+ json_object *telemetry_header = NULL;
+ json_object *COD_offset = NULL;
+ json_object *reason_id = NULL;
+
+ if (!json_object_object_get_ex(tl->root, "telemetryHeader", &telemetry_header))
+ return;
+ if (!json_object_object_get_ex(telemetry_header, "reasonIdentifier", &reason_id))
+ return;
+ if (!json_object_object_get_ex(reason_id, "OemDataMapOffset", &COD_offset))
+ return;
+
+ __u64 offset = json_object_get_int(COD_offset);
+
+ if (offset == 0) {
+ return;
+ }
+
+ if ((offset + sizeof(struct cod_header)) > tl->log_size) {
+ SOLIDIGM_LOG_WARNING("Warning: COD map header out of bounds.");
+ return;
+ }
+
+ const struct cod_map *data = (struct cod_map *) (((__u8 *)tl->log ) + offset);
+
+ uint32_t signature = be32_to_cpu(data->header.Signature);
+ if ( signature != OEMSIGNATURE){
+ SOLIDIGM_LOG_WARNING("Warning: Unsupported COD data signature %x!", signature);
+ return;
+ }
+ if ((offset + data->header.MapSizeInBytes) > tl->log_size){
+ SOLIDIGM_LOG_WARNING("Warning: COD map data out of bounds.");
+ return;
+ }
+
+ json_object *cod = json_create_object();
+ json_object_object_add(tl->root, "cod", cod);
+
+ for (int i =0 ; i < data->header.EntryCount; i++) {
+ if ((offset + sizeof(struct cod_header) + (i + 1) * sizeof(struct cod_item)) >
+ tl->log_size){
+ SOLIDIGM_LOG_WARNING("Warning: COD data out of bounds at item %d!", i);
+ return;
+ }
+ struct cod_item item = data->items[i];
+ if (item.DataFieldOffset + item.DataFieldOffset > tl->log_size) {
+ continue;
+ }
+ if (item.dataInvalid) {
+ continue;
+ }
+ uint8_t *val = ((uint8_t *)tl->log )+ item.DataFieldOffset;
+ const char *key = getOemDataMapDescription(item.DataFieldMapUid);
+ switch(item.dataFieldType){
+ case(INTEGER):
+ if (item.issigned) {
+ json_object_object_add(cod, key,
+ json_object_new_int64(le64_to_cpu(*(uint64_t *)val)));
+ } else {
+ json_object_add_value_uint64(cod, key, le64_to_cpu(*(uint64_t *)val));
+ }
+ break;
+ case(FLOAT):
+ json_object_add_value_float(cod, key, *(float *) val);
+ break;
+ case(STRING):
+ json_object_object_add(cod, key,
+ json_object_new_string_len((const char *)val, item.DataFieldSizeInBytes));
+ break;
+ case(TWO_BYTE_ASCII):
+ json_object_object_add(cod, key,
+ json_object_new_string_len((const char *)val,2));
+ break;
+ case(FOUR_BYTE_ASCII):
+ json_object_object_add(cod, key,
+ json_object_new_string_len((const char *)val, 4));
+ break;
+ default:
+ SOLIDIGM_LOG_WARNING("Warning: Unknown COD field type (%d)", item.DataFieldMapUid);
+
+ }
+ }
+}
diff --git a/plugins/solidigm/solidigm-telemetry/cod.h b/plugins/solidigm/solidigm-telemetry/cod.h
new file mode 100644
index 0000000..032ccdc
--- /dev/null
+++ b/plugins/solidigm/solidigm-telemetry/cod.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright (c) 2022 Solidigm.
+ *
+ * Author: leonardo.da.cunha@solidigm.com
+ */
+
+#include "telemetry-log.h"
+void solidigm_telemetry_log_cod_parse(struct telemetry_log *tl);
diff --git a/plugins/solidigm/solidigm-telemetry/config.c b/plugins/solidigm/solidigm-telemetry/config.c
new file mode 100644
index 0000000..781d786
--- /dev/null
+++ b/plugins/solidigm/solidigm-telemetry/config.c
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright (c) 2022 Solidigm.
+ *
+ * Author: leonardo.da.cunha@solidigm.com
+ */
+#include <stdbool.h>
+#include "util/json.h"
+#include <stdio.h>
+
+// max 16 bit unsigned integer nummber 65535
+#define MAX_16BIT_NUM_AS_STRING_SIZE 6
+
+static bool config_get_by_version(const json_object *obj, int version_major,
+ int version_minor, json_object **value)
+{
+ char str_key[MAX_16BIT_NUM_AS_STRING_SIZE];
+ char str_subkey[MAX_16BIT_NUM_AS_STRING_SIZE];
+
+ snprintf(str_key, sizeof(str_key), "%d", version_major);
+ snprintf(str_subkey, sizeof(str_subkey), "%d", version_minor);
+ json_object *major_obj = NULL;
+
+ if (!json_object_object_get_ex(obj, str_key, &major_obj))
+ return false;
+ if (!json_object_object_get_ex(major_obj, str_subkey, value))
+ return false;
+ return value != NULL;
+}
+
+bool solidigm_config_get_by_token_version(const json_object *obj, int token_id,
+ int version_major, int version_minor,
+ json_object **value)
+{
+ json_object *token_obj = NULL;
+ char str_key[MAX_16BIT_NUM_AS_STRING_SIZE];
+
+ snprintf(str_key, sizeof(str_key), "%d", token_id);
+ if (!json_object_object_get_ex(obj, str_key, &token_obj))
+ return false;
+ if (!config_get_by_version(token_obj, version_major, version_minor, value))
+ return false;
+ return value != NULL;
+}
diff --git a/plugins/solidigm/solidigm-telemetry/config.h b/plugins/solidigm/solidigm-telemetry/config.h
new file mode 100644
index 0000000..bea84fb
--- /dev/null
+++ b/plugins/solidigm/solidigm-telemetry/config.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright (c) 2022 Solidigm.
+ *
+ * Author: leonardo.da.cunha@solidigm.com
+ */
+#include <stdbool.h>
+#include "util/json.h"
+
+bool solidigm_config_get_by_token_version(const json_object *obj, int key, int subkey, int subsubkey, json_object **value);
diff --git a/plugins/solidigm/solidigm-telemetry/data-area.c b/plugins/solidigm/solidigm-telemetry/data-area.c
new file mode 100644
index 0000000..7233e8f
--- /dev/null
+++ b/plugins/solidigm/solidigm-telemetry/data-area.c
@@ -0,0 +1,424 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright (c) 2022 Solidigm.
+ *
+ * Author: leonardo.da.cunha@solidigm.com
+ */
+
+#include "common.h"
+#include "data-area.h"
+#include "config.h"
+#include <ctype.h>
+
+#define SIGNED_INT_PREFIX "int"
+#define BITS_IN_BYTE 8
+
+#define MAX_WARNING_SIZE 1024
+
+static bool telemetry_log_get_value(const struct telemetry_log *tl,
+ uint32_t offset_bit, uint32_t size_bit,
+ bool is_signed, json_object **val_obj)
+{
+ uint32_t offset_bit_from_byte;
+ uint32_t additional_size_byte;
+ uint32_t offset_byte;
+ uint32_t val;
+
+ if (size_bit == 0) {
+ char err_msg[MAX_WARNING_SIZE];
+
+ snprintf(err_msg, MAX_WARNING_SIZE,
+ "Value with size_bit=0 not supported.");
+ *val_obj = json_object_new_string(err_msg);
+
+ return false;
+ }
+ additional_size_byte = (size_bit - 1) ? (size_bit - 1) / BITS_IN_BYTE : 0;
+ offset_byte = offset_bit / BITS_IN_BYTE;
+
+ if (offset_byte > (tl->log_size - additional_size_byte)) {
+ char err_msg[MAX_WARNING_SIZE];
+
+ snprintf(err_msg, MAX_WARNING_SIZE,
+ "Value offset greater than binary size (%u > %zu).",
+ offset_byte, tl->log_size);
+ *val_obj = json_object_new_string(err_msg);
+
+ return false;
+ }
+
+ offset_bit_from_byte = offset_bit - (offset_byte * BITS_IN_BYTE);
+
+ if ((size_bit + offset_bit_from_byte) > (sizeof(uint64_t) * BITS_IN_BYTE)) {
+ char err_msg[MAX_WARNING_SIZE];
+
+ snprintf(err_msg, MAX_WARNING_SIZE,
+ "Value crossing 64 bit, byte aligned bounday, "
+ "not supported. size_bit=%u, offset_bit_from_byte=%u.",
+ size_bit, offset_bit_from_byte);
+ *val_obj = json_object_new_string(err_msg);
+
+ return false;
+ }
+
+ val = *(uint64_t *)(((char *)tl->log) + offset_byte);
+ val >>= offset_bit_from_byte;
+ if (size_bit < 64)
+ val &= (1ULL << size_bit) - 1;
+ if (is_signed) {
+ if (val >> (size_bit - 1))
+ val |= -1ULL << size_bit;
+ *val_obj = json_object_new_int64(val);
+ } else {
+ *val_obj = json_object_new_uint64(val);
+ }
+
+ return true;
+}
+
+static int telemetry_log_structure_parse(const struct telemetry_log *tl,
+ json_object *struct_def,
+ size_t parent_offset_bit,
+ json_object *output,
+ json_object *metadata)
+{
+ json_object *obj_arraySizeArray = NULL;
+ json_object *obj = NULL;
+ json_object *obj_memberList;
+ json_object *major_dimension;
+ json_object *sub_output;
+ bool is_enumeration = false;
+ bool has_member_list;
+ const char *type = "";
+ const char *name;
+ size_t array_rank;
+ size_t offset_bit;
+ size_t size_bit;
+ uint32_t linear_array_pos_bit;
+
+ if (!json_object_object_get_ex(struct_def, "name", &obj)) {
+ SOLIDIGM_LOG_WARNING("Warning: Structure definition missing property 'name': %s",
+ json_object_to_json_string(struct_def));
+ return -1;
+ }
+
+ name = json_object_get_string(obj);
+
+ if (metadata) {
+ json_object_get(obj);
+ json_object_object_add(metadata, "objName", obj);
+ }
+
+ if (json_object_object_get_ex(struct_def, "type", &obj))
+ type = json_object_get_string(obj);
+
+ if (!json_object_object_get_ex(struct_def, "offsetBit", &obj)) {
+ SOLIDIGM_LOG_WARNING("Warning: Structure definition missing "
+ "property 'offsetBit': %s",
+ json_object_to_json_string(struct_def));
+ return -1;
+ }
+
+ offset_bit = json_object_get_uint64(obj);
+
+ if (!json_object_object_get_ex(struct_def, "sizeBit", &obj)) {
+ SOLIDIGM_LOG_WARNING("Warning: Structure definition missing "
+ "property 'sizeBit': %s",
+ json_object_to_json_string(struct_def));
+ return -1;
+ }
+
+ size_bit = json_object_get_uint64(obj);
+
+ if (json_object_object_get_ex(struct_def, "enum", &obj))
+ is_enumeration = json_object_get_boolean(obj);
+
+ has_member_list = json_object_object_get_ex(struct_def,
+ "memberList",
+ &obj_memberList);
+
+ if (!json_object_object_get_ex(struct_def, "arraySize",
+ &obj_arraySizeArray)) {
+ SOLIDIGM_LOG_WARNING("Warning: Structure definition missing "
+ "property 'arraySize': %s",
+ json_object_to_json_string(struct_def));
+ return -1;
+ }
+
+ array_rank = json_object_array_length(obj_arraySizeArray);
+ if (array_rank == 0) {
+ SOLIDIGM_LOG_WARNING("Warning: Structure property 'arraySize' "
+ "don't support flexible array: %s",
+ json_object_to_json_string(struct_def));
+ return -1;
+ }
+ uint32_t array_size_dimension[array_rank];
+
+ for (size_t i = 0; i < array_rank; i++) {
+ json_object *dimension = json_object_array_get_idx(obj_arraySizeArray, i);
+
+ array_size_dimension[i] = json_object_get_uint64(dimension);
+ major_dimension = dimension;
+ }
+ if (array_rank > 1) {
+ uint32_t linear_pos_per_index = array_size_dimension[0];
+ uint32_t prev_index_offset_bit = 0;
+ json_object *dimension_output;
+
+ for (int i = 1; i < (array_rank - 1); i++)
+ linear_pos_per_index *= array_size_dimension[i];
+
+ dimension_output = json_create_array();
+ if (json_object_get_type(output) == json_type_array)
+ json_object_array_add(output, dimension_output);
+ else
+ json_object_add_value_array(output, name, dimension_output);
+
+ /*
+ * Make sure major_dimension object will not be
+ * deleted from memory when deleted from array
+ */
+ json_object_get(major_dimension);
+ json_object_array_del_idx(obj_arraySizeArray, array_rank - 1, 1);
+
+ for (int i = 0 ; i < array_size_dimension[0]; i++) {
+ json_object *sub_array = json_create_array();
+ size_t offset;
+
+ offset = parent_offset_bit + prev_index_offset_bit;
+
+ json_object_array_add(dimension_output, sub_array);
+ telemetry_log_structure_parse(tl, struct_def,
+ offset, sub_array, NULL);
+ prev_index_offset_bit += linear_pos_per_index * size_bit;
+ }
+
+ json_object_array_put_idx(obj_arraySizeArray, array_rank - 1,
+ major_dimension);
+
+ return 0;
+ }
+
+ linear_array_pos_bit = 0;
+ sub_output = output;
+
+ if (array_size_dimension[0] > 1) {
+ sub_output = json_create_array();
+ if (json_object_get_type(output) == json_type_array)
+ json_object_array_add(output, sub_output);
+ else
+ json_object_add_value_array(output, name, sub_output);
+ }
+
+ for (uint32_t j = 0; j < array_size_dimension[0]; j++) {
+ if (is_enumeration || !has_member_list) {
+ bool is_signed = !strncmp(type, SIGNED_INT_PREFIX, sizeof(SIGNED_INT_PREFIX)-1);
+ json_object *val_obj;
+ size_t offset;
+
+ offset = parent_offset_bit + offset_bit + linear_array_pos_bit;
+ if (telemetry_log_get_value(tl, offset, size_bit, is_signed, &val_obj)) {
+ if (array_size_dimension[0] > 1)
+ json_object_array_put_idx(sub_output, j, val_obj);
+ else
+ json_object_object_add(sub_output, name, val_obj);
+ } else {
+ SOLIDIGM_LOG_WARNING("Warning: %s From property '%s', "
+ "array index %u, structure definition: %s",
+ json_object_get_string(val_obj),
+ name, j, json_object_to_json_string(struct_def));
+ json_free_object(val_obj);
+ }
+ } else {
+ json_object *sub_sub_output = json_object_new_object();
+ int num_members;
+
+ if (array_size_dimension[0] > 1)
+ json_object_array_put_idx(sub_output, j, sub_sub_output);
+ else
+ json_object_add_value_object(sub_output, name, sub_sub_output);
+
+ num_members = json_object_array_length(obj_memberList);
+ for (int k = 0; k < num_members; k++) {
+ json_object *member = json_object_array_get_idx(obj_memberList, k);
+ size_t offset;
+
+ offset = parent_offset_bit + offset_bit + linear_array_pos_bit;
+ telemetry_log_structure_parse(tl, member, offset,
+ sub_sub_output, NULL);
+ }
+ }
+ linear_array_pos_bit += size_bit;
+ }
+ return 0;
+}
+
+static int telemetry_log_data_area_get_offset(const struct telemetry_log *tl,
+ enum nvme_telemetry_da da,
+ uint32_t *offset, uint32_t *size)
+{
+ uint32_t offset_blocks = 1;
+ uint32_t last_block = tl->log->dalb1;
+ uint32_t last;
+
+ switch (da) {
+ case NVME_TELEMETRY_DA_1:
+ offset_blocks = 1;
+ last_block = tl->log->dalb1;
+ break;
+ case NVME_TELEMETRY_DA_2:
+ offset_blocks = tl->log->dalb1 + 1;
+ last_block = tl->log->dalb2;
+ break;
+ case NVME_TELEMETRY_DA_3:
+ offset_blocks = tl->log->dalb2 + 1;
+ last_block = tl->log->dalb3;
+ break;
+ case NVME_TELEMETRY_DA_4:
+ offset_blocks = tl->log->dalb3 + 1;
+ last_block = tl->log->dalb4;
+ break;
+ default:
+ return -1;
+ }
+
+ *offset = offset_blocks * NVME_LOG_TELEM_BLOCK_SIZE;
+ last = (last_block + 1) * NVME_LOG_TELEM_BLOCK_SIZE;
+ *size = last - *offset;
+ if ((*offset > tl->log_size) || (last > tl->log_size) || (last <= *offset)) {
+ SOLIDIGM_LOG_WARNING("Warning: Data Area %d don't fit this Telemetry log.", da);
+ return -1;
+ }
+
+ return 0;
+}
+
+struct toc_item {
+ uint32_t OffsetBytes;
+ uint32_t ContentSizeBytes;
+};
+
+struct data_area_header {
+ uint8_t versionMajor;
+ uint8_t versionMinor;
+ uint16_t TableOfContentsCount;
+ uint32_t DataAreaSize;
+ uint8_t Reserved[8];
+};
+
+struct table_of_contents {
+ struct data_area_header header;
+ struct toc_item items[];
+};
+
+struct telemetry_object_header {
+ uint16_t versionMajor;
+ uint16_t versionMinor;
+ uint32_t Token;
+ uint8_t CoreId;
+ uint8_t Reserved[3];
+};
+
+
+static void telemetry_log_data_area_toc_parse(const struct telemetry_log *tl,
+ enum nvme_telemetry_da da,
+ json_object *toc_array,
+ json_object *tele_obj_array)
+{
+
+ const struct telemetry_object_header *header;
+ const struct table_of_contents *toc;
+ char *payload;
+ uint32_t da_offset;
+ uint32_t da_size;
+
+ if (telemetry_log_data_area_get_offset(tl, da, &da_offset, &da_size))
+ return;
+
+ toc = (struct table_of_contents *)(((char *)tl->log) + da_offset);
+ payload = (char *) tl->log;
+
+ for (int i = 0; i < toc->header.TableOfContentsCount; i++) {
+ json_object *structure_definition = NULL;
+ json_object *toc_item;
+ uint32_t obj_offset;
+ bool has_struct;
+
+ if ((char *)&toc->items[i] > (((char *)toc) + da_size - sizeof(const struct toc_item))) {
+ SOLIDIGM_LOG_WARNING("Warning: Data Area %d, "
+ "Table of Contents item %d "
+ "crossed Data Area size.", da, i);
+ return;
+ }
+
+ obj_offset = toc->items[i].OffsetBytes;
+ if ((obj_offset + sizeof(const struct telemetry_object_header)) > da_size) {
+ SOLIDIGM_LOG_WARNING("Warning: Data Area %d, item %d "
+ "data, crossed Data Area size.", da, i);
+ continue;
+ }
+
+ toc_item = json_create_object();
+ json_object_array_add(toc_array, toc_item);
+ json_object_add_value_uint(toc_item, "dataArea", da);
+ json_object_add_value_uint(toc_item, "dataAreaIndex", i);
+ json_object_add_value_uint(toc_item, "dataAreaOffset", obj_offset);
+ json_object_add_value_uint(toc_item, "fileOffset", obj_offset + da_offset);
+ json_object_add_value_uint(toc_item, "size", toc->items[i].ContentSizeBytes);
+
+ header = (const struct telemetry_object_header *) (payload + da_offset + obj_offset);
+ json_object_add_value_uint(toc_item, "telemMajor", header->versionMajor);
+ json_object_add_value_uint(toc_item, "telemMinor", header->versionMinor);
+ json_object_add_value_uint(toc_item, "objectId", header->Token);
+ json_object_add_value_uint(toc_item, "mediaBankId", header->CoreId);
+
+ has_struct = solidigm_config_get_by_token_version(tl->configuration,
+ header->Token,
+ header->versionMajor,
+ header->versionMinor,
+ &structure_definition);
+
+ if (has_struct) {
+ json_object *tele_obj_item = json_create_object();
+
+ json_object_array_add(tele_obj_array, tele_obj_item);
+ json_object_get(toc_item);
+ json_object_add_value_object(tele_obj_item, "metadata", toc_item);
+ json_object *parsed_struct = json_object_new_object();
+
+ json_object_add_value_object(tele_obj_item, "objectData", parsed_struct);
+ json_object *obj_hasTelemObjHdr = NULL;
+ uint32_t header_offset = sizeof(const struct telemetry_object_header);
+ uint32_t file_offset;
+
+ if (json_object_object_get_ex(structure_definition,
+ "hasTelemObjHdr",
+ &obj_hasTelemObjHdr)) {
+ bool hasHeader = json_object_get_boolean(obj_hasTelemObjHdr);
+
+ if (hasHeader)
+ header_offset = 0;
+ }
+
+ file_offset = da_offset + obj_offset + header_offset;
+ telemetry_log_structure_parse(tl, structure_definition,
+ BITS_IN_BYTE * file_offset,
+ parsed_struct, toc_item);
+ }
+ }
+}
+
+int solidigm_telemetry_log_data_areas_parse(const struct telemetry_log *tl,
+ enum nvme_telemetry_da last_da)
+{
+ json_object *tele_obj_array = json_create_array();
+ json_object *toc_array = json_create_array();
+
+ json_object_add_value_array(tl->root, "tableOfContents", toc_array);
+ json_object_add_value_array(tl->root, "telemetryObjects", tele_obj_array);
+
+ for (enum nvme_telemetry_da da = NVME_TELEMETRY_DA_1; da <= last_da; da++)
+ telemetry_log_data_area_toc_parse(tl, da, toc_array, tele_obj_array);
+
+ return 0;
+}
diff --git a/plugins/solidigm/solidigm-telemetry/data-area.h b/plugins/solidigm/solidigm-telemetry/data-area.h
new file mode 100644
index 0000000..095eb64
--- /dev/null
+++ b/plugins/solidigm/solidigm-telemetry/data-area.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright (c) 2022 Solidigm.
+ *
+ * Author: leonardo.da.cunha@solidigm.com
+ */
+#include "common.h"
+#include "telemetry-log.h"
+
+int solidigm_telemetry_log_data_areas_parse(const struct telemetry_log *tl,
+ enum nvme_telemetry_da last_da);
diff --git a/plugins/solidigm/solidigm-telemetry/header.c b/plugins/solidigm/solidigm-telemetry/header.c
new file mode 100644
index 0000000..72b2d97
--- /dev/null
+++ b/plugins/solidigm/solidigm-telemetry/header.c
@@ -0,0 +1,199 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright (c) 2022 Solidigm.
+ *
+ * Author: leonardo.da.cunha@solidigm.com
+ */
+
+#include "common.h"
+#include "header.h"
+
+#pragma pack(push, reason_indentifier, 1)
+struct reason_indentifier_1_0
+{
+ uint16_t versionMajor;
+ uint16_t versionMinor;
+ uint32_t reasonCode; //! 0 denotes no issue. All other values denote a potential issue.
+ char DriveStatus[20]; //! Drive Status String (for example: "Healthy", "*BAD_CONTEXT_2020")
+ char FirmwareVersion[12]; //! Similar to IdentifyController.FR
+ char BootloaderVersion[12]; //! Bootloader version string
+ char SerialNumber[20]; //! Device serial number
+ uint8_t Reserved[56]; //! Reserved for future usage
+};
+static_assert(sizeof(const struct reason_indentifier_1_0) ==
+ MEMBER_SIZE(struct nvme_telemetry_log, rsnident),
+ "Size mismatch for reason_indentifier_1_0");
+
+struct reason_indentifier_1_1
+{
+ uint16_t versionMajor;
+ uint16_t versionMinor;
+ uint32_t reasonCode; //! 0 denotes no issue. All other values denote a potential issue.
+ char DriveStatus[20]; //! Drive Status String (for example: "Healthy", "*BAD_CONTEXT_2020")
+ char FirmwareVersion[12]; //! Similar to IdentifyController.FR
+ char BootloaderVersion[12]; //! Bootloader version string
+ char SerialNumber[20]; //! Device serial number
+ uint64_t OemDataMapOffset; //! Customer Data Map Object Log Offset
+ uint8_t TelemetryMajorVersion; //! Shadow of version in TOC
+ uint8_t TelemetryMinorVersion; //! Shadow of version in TOC
+ uint8_t Reserved[46]; //! Reserved for future usage
+};
+static_assert(sizeof(const struct reason_indentifier_1_1) ==
+ MEMBER_SIZE(struct nvme_telemetry_log, rsnident),
+ "Size mismatch for reason_indentifier_1_1");
+
+struct reason_indentifier_1_2
+{
+ uint16_t versionMajor;
+ uint16_t versionMinor;
+ uint32_t reasonCode; //! 0 denotes no issue. All other values denote a potential issue.
+ char DriveStatus[20]; //! Drive Status String (for example: "Healthy", "*BAD_CONTEXT_2020")
+ uint8_t Reserved1[24]; //! pad over Fields removed from version 1.1
+ char SerialNumber[20]; //! Device serial number
+ uint64_t OemDataMapOffset; //! Customer Data Map Object Log Offset
+ uint8_t TelemetryMajorVersion; //! Shadow of version in TOC
+ uint8_t TelemetryMinorVersion; //! Shadow of version in TOC
+ uint8_t ProductFamilyId;
+ uint8_t Reserved2[5]; //! Reserved for future usage
+ uint8_t DualPortReserved[40]; //! Reserved for dual port
+};
+static_assert(sizeof(const struct reason_indentifier_1_2) ==
+ MEMBER_SIZE(struct nvme_telemetry_log, rsnident),
+ "Size mismatch for reason_indentifier_1_2");
+#pragma pack(pop, reason_indentifier)
+
+static void telemetry_log_reason_id_parse1_0_ext(const struct telemetry_log *tl,
+ json_object *reason_id)
+{
+ const struct reason_indentifier_1_0 *ri;
+ json_object *reserved;
+
+ ri = (struct reason_indentifier_1_0 *) tl->log->rsnident;
+ json_object_object_add(reason_id, "FirmwareVersion", json_object_new_string_len(ri->FirmwareVersion, sizeof(ri->FirmwareVersion)));
+ json_object_object_add(reason_id, "BootloaderVersion", json_object_new_string_len(ri->BootloaderVersion, sizeof(ri->BootloaderVersion)));
+ json_object_object_add(reason_id, "SerialNumber", json_object_new_string_len(ri->SerialNumber, sizeof(ri->SerialNumber)));
+
+ reserved = json_create_array();
+ json_object_add_value_array(reason_id, "Reserved", reserved);
+ for ( int i=0; i < sizeof(ri->Reserved); i++) {
+ json_object *val = json_object_new_int(ri->Reserved[i]);
+ json_object_array_add(reserved, val);
+ }
+}
+
+static void telemetry_log_reason_id_parse1_1_ext(const struct telemetry_log *tl,
+ json_object *reason_id)
+{
+ const struct reason_indentifier_1_1 *ri;
+ json_object *reserved;
+
+ ri = (struct reason_indentifier_1_1 *) tl->log->rsnident;
+ json_object_object_add(reason_id, "FirmwareVersion", json_object_new_string_len(ri->FirmwareVersion, sizeof(ri->FirmwareVersion)));
+ json_object_object_add(reason_id, "BootloaderVersion", json_object_new_string_len(ri->BootloaderVersion, sizeof(ri->BootloaderVersion)));
+ json_object_object_add(reason_id, "SerialNumber", json_object_new_string_len(ri->SerialNumber, sizeof(ri->SerialNumber)));
+ json_object_add_value_uint64(reason_id, "OemDataMapOffset", le64_to_cpu(ri->OemDataMapOffset));
+ json_object_add_value_uint(reason_id, "TelemetryMajorVersion", le16_to_cpu(ri->TelemetryMajorVersion));
+ json_object_add_value_uint(reason_id, "TelemetryMinorVersion", le16_to_cpu(ri->TelemetryMinorVersion));
+
+ reserved = json_create_array();
+ json_object_add_value_array(reason_id, "Reserved", reserved);
+ for (int i = 0; i < sizeof(ri->Reserved); i++) {
+ json_object *val = json_object_new_int(ri->Reserved[i]);
+ json_object_array_add(reserved, val);
+ }
+}
+
+static void telemetry_log_reason_id_parse1_2_ext(const struct telemetry_log *tl,
+ json_object *reason_id)
+{
+ const struct reason_indentifier_1_2 *ri;
+ json_object *dp_reserved;
+ json_object *reserved;
+
+ ri = (struct reason_indentifier_1_2 *) tl->log->rsnident;
+
+ json_object_object_add(reason_id, "SerialNumber", json_object_new_string_len(ri->SerialNumber, sizeof(ri->SerialNumber)));
+ json_object_add_value_uint64(reason_id, "OemDataMapOffset", le64_to_cpu(ri->OemDataMapOffset));
+ json_object_add_value_uint(reason_id, "TelemetryMajorVersion", le16_to_cpu(ri->TelemetryMajorVersion));
+ json_object_add_value_uint(reason_id, "TelemetryMinorVersion", le16_to_cpu(ri->TelemetryMinorVersion));
+ json_object_add_value_uint(reason_id, "ProductFamilyId", ri->ProductFamilyId);
+
+ reserved = json_create_array();
+ json_object_add_value_array(reason_id, "Reserved2", reserved);
+ for (int i = 0; i < sizeof(ri->Reserved2); i++) {
+ json_object *val = json_object_new_int(ri->Reserved2[i]);
+ json_object_array_add(reserved, val);
+ }
+
+ dp_reserved = json_create_array();
+ json_object_add_value_array(reason_id, "DualPortReserved", dp_reserved);
+ for (int i = 0; i < sizeof(ri->DualPortReserved); i++) {
+ json_object *val = json_object_new_int(ri->DualPortReserved[i]);
+ json_object_array_add(dp_reserved, val);
+ }
+}
+
+static void solidigm_telemetry_log_reason_id_parse(const struct telemetry_log *tl, json_object *reason_id)
+{
+ const struct reason_indentifier_1_0 *ri1_0 =
+ (struct reason_indentifier_1_0 *) tl->log->rsnident;
+ __u16 version_major = le16_to_cpu(ri1_0->versionMajor);
+ __u16 version_minor = le16_to_cpu(ri1_0->versionMinor);
+
+ json_object_add_value_uint(reason_id, "versionMajor", version_major);
+ json_object_add_value_uint(reason_id, "versionMinor", version_minor);
+ json_object_add_value_uint(reason_id, "reasonCode", le32_to_cpu(ri1_0->reasonCode));
+ json_object_add_value_object(reason_id, "DriveStatus", json_object_new_string_len(ri1_0->DriveStatus, sizeof(ri1_0->DriveStatus)));
+ if (version_major == 1) {
+ switch (version_minor) {
+ case 0:
+ telemetry_log_reason_id_parse1_0_ext(tl, reason_id);
+ break;
+ case 1:
+ telemetry_log_reason_id_parse1_1_ext(tl, reason_id);
+ break;
+ default:
+ telemetry_log_reason_id_parse1_2_ext(tl, reason_id);
+ }
+ }
+}
+
+bool solidigm_telemetry_log_header_parse(const struct telemetry_log *tl)
+{
+ const struct nvme_telemetry_log *log;
+ json_object *ieee_oui_id;
+ json_object *reason_id;
+ json_object *header;
+
+ if (tl->log_size < sizeof(const struct nvme_telemetry_log)) {
+ SOLIDIGM_LOG_WARNING("Telemetry log too short.");
+ return false;
+ }
+
+ header = json_create_object();
+
+ json_object_object_add(tl->root, "telemetryHeader", header);
+ log = tl->log;
+
+ json_object_add_value_uint(header, "logIdentifier", log->lpi);
+ ieee_oui_id = json_create_array();
+
+ json_object_object_add(header, "ieeeOuiIdentifier", ieee_oui_id);
+ for (int i = 0; i < sizeof(log->ieee); i++) {
+ json_object *val = json_object_new_int(log->ieee[i]);
+
+ json_object_array_add(ieee_oui_id, val);
+ }
+ json_object_add_value_uint(header, "dataArea1LastBlock", log->dalb1);
+ json_object_add_value_uint(header, "dataArea2LastBlock", log->dalb2);
+ json_object_add_value_uint(header, "dataArea3LastBlock", log->dalb3);
+ json_object_add_value_uint(header, "hostInitiatedDataGeneration", log->hostdgn);
+ json_object_add_value_uint(header, "controllerInitiatedDataAvailable", log->ctrlavail);
+ json_object_add_value_uint(header, "controllerInitiatedDataGeneration", log->ctrldgn);
+
+ reason_id = json_create_object();
+ json_object_add_value_object(header, "reasonIdentifier", reason_id);
+ solidigm_telemetry_log_reason_id_parse(tl, reason_id);
+
+ return true;
+}
diff --git a/plugins/solidigm/solidigm-telemetry/header.h b/plugins/solidigm/solidigm-telemetry/header.h
new file mode 100644
index 0000000..027af55
--- /dev/null
+++ b/plugins/solidigm/solidigm-telemetry/header.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright (c) 2022 Solidigm.
+ *
+ * Author: leonardo.da.cunha@solidigm.com
+ */
+
+#include "telemetry-log.h"
+bool solidigm_telemetry_log_header_parse(const struct telemetry_log *tl);
diff --git a/plugins/solidigm/solidigm-telemetry/meson.build b/plugins/solidigm/solidigm-telemetry/meson.build
new file mode 100644
index 0000000..53ab452
--- /dev/null
+++ b/plugins/solidigm/solidigm-telemetry/meson.build
@@ -0,0 +1,6 @@
+sources += [
+ 'plugins/solidigm/solidigm-telemetry/cod.c',
+ 'plugins/solidigm/solidigm-telemetry/header.c',
+ 'plugins/solidigm/solidigm-telemetry/config.c',
+ 'plugins/solidigm/solidigm-telemetry/data-area.c',
+]
diff --git a/plugins/solidigm/solidigm-telemetry/telemetry-log.h b/plugins/solidigm/solidigm-telemetry/telemetry-log.h
new file mode 100644
index 0000000..ef4ec5d
--- /dev/null
+++ b/plugins/solidigm/solidigm-telemetry/telemetry-log.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Copyright (c) 2022 Solidigm.
+ *
+ * Author: leonardo.da.cunha@solidigm.com
+ */
+
+#ifndef _SOLIDIGM_TELEMETRY_LOG_H
+#define _SOLIDIGM_TELEMETRY_LOG_H
+
+#include "libnvme.h"
+#include "util/json.h"
+#include <assert.h>
+
+#if !defined __cplusplus
+#define static_assert _Static_assert
+#endif
+
+#define VA_ARGS(...), ##__VA_ARGS__
+#define SOLIDIGM_LOG_WARNING(format, ...) fprintf(stderr, format"\n" VA_ARGS(__VA_ARGS__))
+
+#define MEMBER_SIZE(type, member) sizeof(((type *)0)->member)
+
+struct telemetry_log {
+ struct nvme_telemetry_log *log;
+ size_t log_size;
+ json_object *root;
+ json_object *configuration;
+};
+
+#endif /* _SOLIDIGM_TELEMETRY_LOG_H */ \ No newline at end of file
diff --git a/plugins/toshiba/toshiba-nvme.c b/plugins/toshiba/toshiba-nvme.c
index cf19352..5540fea 100644
--- a/plugins/toshiba/toshiba-nvme.c
+++ b/plugins/toshiba/toshiba-nvme.c
@@ -361,11 +361,11 @@ struct nvme_xdn_smart_log_c0 {
__u8 resv[512 - NR_SMART_ITEMS_C0];
};
-static void default_show_vendor_log_c0(int fd, __u32 nsid, const char *devname,
+static void default_show_vendor_log_c0(struct nvme_dev *dev, __u32 nsid,
struct nvme_xdn_smart_log_c0 *smart)
{
printf("Vendor Log Page Directory 0xC0 for NVME device:%s namespace-id:%x\n",
- devname, nsid);
+ dev->name, 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]);
@@ -375,8 +375,8 @@ static void default_show_vendor_log_c0(int fd, __u32 nsid, const char *devname,
printf("SMART Attributes : %u \n", smart->items[SMART_ATTRIBUTES_C0]);
}
-static int nvme_get_vendor_log(int fd, __u32 namespace_id, int log_page,
- const char* const filename)
+static int nvme_get_vendor_log(struct nvme_dev *dev, __u32 namespace_id,
+ int log_page, const char* const filename)
{
int err;
void* log = NULL;
@@ -388,11 +388,12 @@ static int nvme_get_vendor_log(int fd, __u32 namespace_id, int log_page,
}
/* Check device supported */
- err = nvme_get_sct_status(fd, MASK_0 | MASK_1);
+ err = nvme_get_sct_status(dev_fd(dev), MASK_0 | MASK_1);
if (err) {
goto end;
}
- err = nvme_get_nsid_log(fd, false, log_page, namespace_id, log_len, log);
+ err = nvme_get_nsid_log(dev_fd(dev), false, log_page, namespace_id,
+ log_len, log);
if (err) {
fprintf(stderr, "%s: couldn't get log 0x%x\n", __func__,
log_page);
@@ -419,8 +420,7 @@ static int nvme_get_vendor_log(int fd, __u32 namespace_id, int log_page,
}
} else {
if (log_page == 0xc0)
- default_show_vendor_log_c0(fd, namespace_id, devicename,
- (struct nvme_xdn_smart_log_c0 *)log);
+ default_show_vendor_log_c0(dev, namespace_id, log);
else
d(log, log_len,16,1);
}
@@ -433,11 +433,12 @@ end:
static int vendor_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- int err, fd;
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;
+ int err;
struct config {
__u32 namespace_id;
@@ -458,8 +459,8 @@ static int vendor_log(int argc, char **argv, struct command *cmd, struct plugin
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0) {
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err) {
fprintf(stderr,"%s: failed to parse arguments\n", __func__);
return EINVAL;
}
@@ -470,22 +471,24 @@ static int vendor_log(int argc, char **argv, struct command *cmd, struct plugin
goto end;
}
- err = nvme_get_vendor_log(fd, cfg.namespace_id, cfg.log, cfg.output_file);
+ err = nvme_get_vendor_log(dev, 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);
- close(fd);
+ dev_close(dev);
return err;
}
static int internal_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- int err, fd;
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;
+ int err;
struct config {
const char* output_file;
@@ -503,8 +506,8 @@ static int internal_log(int argc, char **argv, struct command *cmd, struct plugi
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0) {
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err) {
fprintf(stderr,"%s: failed to parse arguments\n", __func__);
return EINVAL;
}
@@ -514,46 +517,48 @@ 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(fd, cfg.output_file, !cfg.prev_log);
+ err = nvme_get_internal_log_file(dev_fd(dev), 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);
- close(fd);
+ dev_close(dev);
return err;
}
static int clear_correctable_errors(int argc, char **argv, struct command *cmd,
struct plugin *plugin)
{
- int err, fd;
char *desc = "Clear PCIe correctable error count.";
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;
OPT_ARGS(opts) = {
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0) {
+ err = parse_and_open(&dev, 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(fd, MASK_0 | MASK_1);
+ err = nvme_get_sct_status(dev_fd(dev), MASK_0 | MASK_1);
if (err)
goto end;
struct nvme_set_features_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.fid = feature_id,
.nsid = namespace_id,
.cdw11 = value,
@@ -573,6 +578,6 @@ static int clear_correctable_errors(int argc, char **argv, struct command *cmd,
end:
if (err > 0)
nvme_show_status(err);
- close(fd);
+ dev_close(dev);
return err;
}
diff --git a/plugins/transcend/transcend-nvme.c b/plugins/transcend/transcend-nvme.c
index a3b739d..024351f 100644
--- a/plugins/transcend/transcend-nvme.c
+++ b/plugins/transcend/transcend-nvme.c
@@ -21,20 +21,20 @@ static int getHealthValue(int argc, char **argv, struct command *cmd, struct plu
{
struct nvme_smart_log smart_log;
char *desc = "Get nvme health percentage.";
- int result=0, fd;
int percent_used = 0, healthvalue=0;
-
+ struct nvme_dev *dev;
+ int result;
+
OPT_ARGS(opts) = {
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
-
- if (fd < 0) {
+ result = parse_and_open(&dev, argc, argv, desc, opts);
+ if (result) {
printf("\nDevice not found \n");;
return -1;
}
- result = nvme_get_log_smart(fd, 0xffffffff, false, &smart_log);
+ result = nvme_get_log_smart(dev_fd(dev), 0xffffffff, false, &smart_log);
if (!result) {
printf("Transcend NVME heath value: ");
percent_used =smart_log.percent_used;
@@ -50,7 +50,7 @@ static int getHealthValue(int argc, char **argv, struct command *cmd, struct plu
}
}
- close(fd);
+ dev_close(dev);
return result;
}
@@ -59,15 +59,16 @@ static int getBadblock(int argc, char **argv, struct command *cmd, struct plugin
{
char *desc = "Get nvme bad block number.";
- int result=0, fd;
+ struct nvme_dev *dev;
+ int result;
OPT_ARGS(opts) = {
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0) {
+ result = parse_and_open(&dev, argc, argv, desc, opts);
+ if (result) {
printf("\nDevice not found \n");;
return -1;
}
@@ -79,11 +80,11 @@ 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(fd, &nvmecmd, NULL);
+ result = nvme_submit_admin_passthru(dev_fd(dev), &nvmecmd, NULL);
if(!result) {
int badblock = data[0];
printf("Transcend NVME badblock count: %d\n",badblock);
}
- close(fd);
+ dev_close(dev);
return result;
}
diff --git a/plugins/virtium/virtium-nvme.c b/plugins/virtium/virtium-nvme.c
index b8cefe6..c8df126 100644
--- a/plugins/virtium/virtium-nvme.c
+++ b/plugins/virtium/virtium-nvme.c
@@ -14,6 +14,7 @@
#include "nvme.h"
#include "libnvme.h"
#include "plugin.h"
+#include "util/types.h"
#define CREATE_CMD
#include "virtium-nvme.h"
@@ -51,18 +52,6 @@ struct vtview_save_log_settings {
const char* test_name;
};
-static long double int128_to_double(__u8 *data)
-{
- int i;
- long double result = 0;
-
- for (i = 0; i < 16; i++) {
- result *= 256;
- result += data[15 - i];
- }
- return result;
-}
-
static void vt_initialize_header_buffer(struct vtview_log_header *pbuff)
{
memset(pbuff->path, 0, sizeof(pbuff->path));
@@ -151,25 +140,25 @@ static void vt_convert_smart_data_to_human_readable_format(struct vtview_smart_l
strcat(text, tempbuff);
snprintf(tempbuff, sizeof(tempbuff), "Percentage_Used;%u;", smart->raw_smart.percent_used);
strcat(text, tempbuff);
- snprintf(tempbuff, sizeof(tempbuff), "Data_Units_Read;%0.Lf;", int128_to_double(smart->raw_smart.data_units_read));
+ snprintf(tempbuff, sizeof(tempbuff), "Data_Units_Read;%s;", uint128_t_to_string(le128_to_cpu(smart->raw_smart.data_units_read)));
strcat(text, tempbuff);
- snprintf(tempbuff, sizeof(tempbuff), "Data_Units_Written;%0.Lf;", int128_to_double(smart->raw_smart.data_units_written));
+ snprintf(tempbuff, sizeof(tempbuff), "Data_Units_Written;%s;", uint128_t_to_string(le128_to_cpu(smart->raw_smart.data_units_written)));
strcat(text, tempbuff);
- snprintf(tempbuff, sizeof(tempbuff), "Host_Read_Commands;%0.Lf;", int128_to_double(smart->raw_smart.host_reads));
+ snprintf(tempbuff, sizeof(tempbuff), "Host_Read_Commands;%s;", uint128_t_to_string(le128_to_cpu(smart->raw_smart.host_reads)));
strcat(text, tempbuff);
- snprintf(tempbuff, sizeof(tempbuff), "Host_Write_Commands;%0.Lf;", int128_to_double(smart->raw_smart.host_writes));
+ snprintf(tempbuff, sizeof(tempbuff), "Host_Write_Commands;%s;", uint128_t_to_string(le128_to_cpu(smart->raw_smart.host_writes)));
strcat(text, tempbuff);
- snprintf(tempbuff, sizeof(tempbuff), "Controller_Busy_Time;%0.Lf;", int128_to_double(smart->raw_smart.ctrl_busy_time));
+ snprintf(tempbuff, sizeof(tempbuff), "Controller_Busy_Time;%s;", uint128_t_to_string(le128_to_cpu(smart->raw_smart.ctrl_busy_time)));
strcat(text, tempbuff);
- snprintf(tempbuff, sizeof(tempbuff), "Power_Cycles;%0.Lf;", int128_to_double(smart->raw_smart.power_cycles));
+ snprintf(tempbuff, sizeof(tempbuff), "Power_Cycles;%s;", uint128_t_to_string(le128_to_cpu(smart->raw_smart.power_cycles)));
strcat(text, tempbuff);
- snprintf(tempbuff, sizeof(tempbuff), "Power_On_Hours;%0.Lf;", int128_to_double(smart->raw_smart.power_on_hours));
+ snprintf(tempbuff, sizeof(tempbuff), "Power_On_Hours;%s;", uint128_t_to_string(le128_to_cpu(smart->raw_smart.power_on_hours)));
strcat(text, tempbuff);
- snprintf(tempbuff, sizeof(tempbuff), "Unsafe_Shutdowns;%0.Lf;", int128_to_double(smart->raw_smart.unsafe_shutdowns));
+ snprintf(tempbuff, sizeof(tempbuff), "Unsafe_Shutdowns;%s;", uint128_t_to_string(le128_to_cpu(smart->raw_smart.unsafe_shutdowns)));
strcat(text, tempbuff);
- snprintf(tempbuff, sizeof(tempbuff), "Media_Errors;%0.Lf;", int128_to_double(smart->raw_smart.media_errors));
+ snprintf(tempbuff, sizeof(tempbuff), "Media_Errors;%s;", uint128_t_to_string(le128_to_cpu(smart->raw_smart.media_errors)));
strcat(text, tempbuff);
- snprintf(tempbuff, sizeof(tempbuff), "Num_Err_Log_Entries;%0.Lf;", int128_to_double(smart->raw_smart.num_err_log_entries));
+ snprintf(tempbuff, sizeof(tempbuff), "Num_Err_Log_Entries;%s;", uint128_t_to_string(le128_to_cpu(smart->raw_smart.num_err_log_entries)));
strcat(text, tempbuff);
snprintf(tempbuff, sizeof(tempbuff), "Warning_Temperature_Time;%u;", le32_to_cpu(smart->raw_smart.warning_temp_time));
strcat(text, tempbuff);
@@ -927,8 +916,7 @@ static void vt_parse_detail_identify(const struct nvme_id_ctrl *ctrl)
static int vt_save_smart_to_vtview_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- int err = 0;
- int fd, ret;
+ int ret, err = 0;
long int total_time = 0;
long int freq_time = 0;
long int cur_time = 0;
@@ -949,6 +937,7 @@ 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;
struct vtview_save_log_settings cfg = {
.run_time_hrs = 20,
@@ -975,10 +964,10 @@ static int vt_save_smart_to_vtview_log(int argc, char **argv, struct command *cm
strcpy(path, argv[1]);
}
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0) {
- printf("Error parse and open (fd = %d)\n", fd);
- return (fd);
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err) {
+ printf("Error parse and open (err = %d)\n", err);
+ return err;
}
printf("Running...\n");
@@ -986,10 +975,10 @@ 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(fd, path, &cfg);
+ ret = vt_update_vtview_log_header(dev_fd(dev), path, &cfg);
if (ret) {
err = EINVAL;
- close(fd);
+ dev_close(dev);
return (err);
}
@@ -1009,7 +998,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(fd, path, &cfg);
+ ret = vt_add_entry_to_log(dev_fd(dev), path, &cfg);
if (ret) {
printf("Cannot update driver log\n");
break;
@@ -1021,15 +1010,15 @@ static int vt_save_smart_to_vtview_log(int argc, char **argv, struct command *cm
fflush(stdout);
}
- close (fd);
+ dev_close(dev);
return (err);
}
static int vt_show_identify(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
- int err = 0;
- int fd ,ret;
+ 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";
@@ -1038,16 +1027,16 @@ static int vt_show_identify(int argc, char **argv, struct command *cmd, struct p
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0) {
- printf("Error parse and open (fd = %d)\n", fd);
- return (fd);
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err) {
+ printf("Error parse and open (err = %d)\n", err);
+ return err;
}
- ret = nvme_identify_ctrl(fd, &ctrl);
+ ret = nvme_identify_ctrl(dev_fd(dev), &ctrl);
if (ret) {
printf("Cannot read identify device\n");
- close (fd);
+ dev_close(dev);
return (-1);
}
@@ -1055,6 +1044,6 @@ 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);
- close(fd);
+ dev_close(dev);
return (err);
}
diff --git a/plugins/wdc/wdc-nvme.c b/plugins/wdc/wdc-nvme.c
index 5f90c76..cf185be 100644
--- a/plugins/wdc/wdc-nvme.c
+++ b/plugins/wdc/wdc-nvme.c
@@ -36,6 +36,7 @@
#include "libnvme.h"
#include "plugin.h"
#include "linux/types.h"
+#include "util/types.h"
#include "nvme-print.h"
#define CREATE_CMD
@@ -77,11 +78,15 @@
#define WDC_NVME_SN650_DEV_ID_3 0x2720
#define WDC_NVME_SN650_DEV_ID_4 0x2721
#define WDC_NVME_SN655_DEV_ID 0x2722
+#define WDC_NVME_SN860_DEV_ID 0x2730
+#define WDC_NVME_SN660_DEV_ID 0x2704
+
+/* This id's are no longer supported, delete ?? */
+#define WDC_NVME_SN550_DEV_ID 0x2708
#define WDC_NVME_SN560_DEV_ID_1 0x2712
#define WDC_NVME_SN560_DEV_ID_2 0x2713
#define WDC_NVME_SN560_DEV_ID_3 0x2714
-#define WDC_NVME_SN860_DEV_ID 0x2730
-#define WDC_NVME_SN550_DEV_ID 0x2708
+
#define WDC_NVME_SXSLCL_DEV_ID 0x2001
#define WDC_NVME_SN520_DEV_ID 0x5003
#define WDC_NVME_SN520_DEV_ID_1 0x5004
@@ -89,8 +94,6 @@
#define WDC_NVME_SN530_DEV_ID 0x5009
#define WDC_NVME_SN720_DEV_ID 0x5002
#define WDC_NVME_SN730A_DEV_ID 0x5006
-#define WDC_NVME_SN730B_DEV_ID 0x3714
-#define WDC_NVME_SN730B_DEV_ID_1 0x3734
#define WDC_NVME_SN740_DEV_ID 0x5015
#define WDC_NVME_SN740_DEV_ID_1 0x5016
#define WDC_NVME_SN740_DEV_ID_2 0x5017
@@ -327,7 +330,7 @@
#define WDC_NVME_SMART_CLOUD_ATTR_LEN 0x200
/* C0 SMART Cloud Attributes Log Page*/
-#define WDC_NVME_GET_SMART_CLOUD_ATTR_LOG_OPCODE 0xC0
+#define WDC_NVME_GET_SMART_CLOUD_ATTR_LOG_ID 0xC0
/* CB - FW Activate History Log Page */
#define WDC_NVME_GET_FW_ACT_HISTORY_LOG_ID 0xCB
@@ -341,7 +344,7 @@
/* C3 Latency Monitor Log Page */
#define WDC_LATENCY_MON_LOG_BUF_LEN 0x200
-#define WDC_LATENCY_MON_OPCODE 0xC3
+#define WDC_LATENCY_MON_LOG_ID 0xC3
#define WDC_LATENCY_MON_VERSION 0x0001
#define WDC_C3_GUID_LENGTH 16
@@ -792,17 +795,18 @@ static NVME_VU_DE_LOGPAGE_LIST deVULogPagesList[] =
{ NVME_DE_LOGPAGE_C0, 0xC0, 512, "0xc0"}
};
-static int wdc_get_serial_name(int fd, char *file, size_t len, const char *suffix);
+static int wdc_get_serial_name(struct nvme_dev *dev, char *file, size_t len,
+ const char *suffix);
static int wdc_create_log_file(char *file, __u8 *drive_log_data,
__u32 drive_log_length);
-static int wdc_do_clear_dump(int fd, __u8 opcode, __u32 cdw12);
-static int wdc_do_dump(int fd, __u32 opcode,__u32 data_len,
+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, char *file, __u32 xfer_size);
-static int wdc_do_crash_dump(int fd, char *file, int type);
-static int wdc_crash_dump(int fd, char *file, int type);
+static int wdc_do_crash_dump(struct nvme_dev *dev, char *file, int type);
+static int wdc_crash_dump(struct nvme_dev *dev, char *file, int type);
static int wdc_get_crash_dump(int argc, char **argv, struct command *command,
struct plugin *plugin);
-static int wdc_do_drive_log(int fd, char *file);
+static int wdc_do_drive_log(struct nvme_dev *dev, char *file);
static int wdc_drive_log(int argc, char **argv, struct command *command,
struct plugin *plugin);
static const char* wdc_purge_mon_status_to_string(__u32 status);
@@ -810,10 +814,11 @@ 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, int fd, __u8 log_id);
+static bool wdc_nvme_check_supported_log_page(nvme_root_t r,
+ struct nvme_dev *dev, __u8 log_id);
static int wdc_clear_pcie_correctable_errors(int argc, char **argv, struct command *command,
struct plugin *plugin);
-static int wdc_do_drive_essentials(nvme_root_t r, int fd, char *dir, char *key);
+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,
struct plugin *plugin);
static int wdc_drive_status(int argc, char **argv, struct command *command,
@@ -822,27 +827,31 @@ static int wdc_clear_assert_dump(int argc, char **argv, struct command *command,
struct plugin *plugin);
static int wdc_drive_resize(int argc, char **argv,
struct command *command, struct plugin *plugin);
-static int wdc_do_drive_resize(int fd, uint64_t new_size);
+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, struct plugin *plugin);
-static int wdc_do_namespace_resize(int fd, __u32 nsid, __u32 op_option);
+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, struct plugin *plugin);
-static int wdc_do_get_reason_id(int fd, char *file, int log_id);
-static int wdc_save_reason_id(int fd, __u8 *rsn_ident, int size);
-static int wdc_clear_reason_id(int fd);
+static int wdc_do_get_reason_id(struct nvme_dev *dev, 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,
struct plugin *plugin);
-static int wdc_do_drive_info(int fd, __u32 *result);
+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,
struct plugin *plugin);
-static __u64 wdc_get_enc_drive_capabilities(nvme_root_t r, int fd);
-static int wdc_enc_get_nic_log(int fd, __u8 log_id, __u32 xfer_size, __u32 data_len, FILE *out);
-static int wdc_enc_submit_move_data(int fd, 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, int fd, __u8 log_id, void **cbs_data);
-static __u32 wdc_get_fw_cust_id(nvme_root_t r, int fd);
+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, FILE *out);
+static int wdc_enc_submit_move_data(struct nvme_dev *dev, 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, void **cbs_data);
+static __u32 wdc_get_fw_cust_id(nvme_root_t r, struct nvme_dev *dev);
/* Drive log data size */
struct wdc_log_size {
@@ -1084,7 +1093,8 @@ struct __attribute__((__packed__)) wdc_ssd_d0_smart_log {
#define WDC_OCP_C1_GUID_LENGTH 16
#define WDC_ERROR_REC_LOG_BUF_LEN 512
#define WDC_ERROR_REC_LOG_ID 0xC1
-#define WDC_ERROR_REC_LOG_VERSION 0002
+#define WDC_ERROR_REC_LOG_VERSION1 0001
+#define WDC_ERROR_REC_LOG_VERSION2 0002
struct __attribute__((__packed__)) wdc_ocp_c1_error_recovery_log {
__le16 panic_reset_wait_time; /* 000 - Panic Reset Wait Time */
@@ -1096,9 +1106,9 @@ struct __attribute__((__packed__)) wdc_ocp_c1_error_recovery_log {
__u8 rsvd1[3]; /* 017 - 3 Reserved Bytes */
__le32 vs_cmd_cdw12; /* 020 - Vendor Specific Command CDW12 */
__le32 vs_cmd_cdw13; /* 024 - Vendor Specific Command CDW13 */
- __u8 vs_cmd_to; /* 028 - Vendor Specific Command Timeout */
- __u8 dev_recovery_action2; /* 029 - Device Recovery Action 2 */
- __u8 dev_recovery_action2_to; /* 030 - Device Recovery Action 2 Timeout */
+ __u8 vs_cmd_to; /* 028 - Vendor Specific Command Timeout V2 */
+ __u8 dev_recovery_action2; /* 029 - Device Recovery Action 2 V2 */
+ __u8 dev_recovery_action2_to; /* 030 - Device Recovery Action 2 Timeout V2*/
__u8 rsvd2[463]; /* 031 - 463 Reserved Bytes */
__le16 log_page_version; /* 494 - Log Page Version */
__u8 log_page_guid[WDC_OCP_C1_GUID_LENGTH]; /* 496 - Log Page GUID */
@@ -1277,27 +1287,15 @@ static double calc_percent(uint64_t numerator, uint64_t denominator)
(uint64_t)(((double)numerator / (double)denominator) * 100) : 0;
}
-static long double int128_to_double(__u8 *data)
-{
- int i;
- long double result = 0;
-
- for (i = 0; i < 16; i++) {
- result *= 256;
- result += data[15 - i];
- }
- return result;
-}
-
-static int wdc_get_pci_ids(nvme_root_t r, uint32_t *device_id,
- uint32_t *vendor_id)
+static int wdc_get_pci_ids(nvme_root_t r, struct nvme_dev *dev,
+ 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, devicename);
+ c = nvme_scan_ctrl(r, dev->name);
if (c) {
snprintf(vid, sizeof(vid), "%s/device/vendor",
nvme_ctrl_get_sysfs_dir(c));
@@ -1305,9 +1303,9 @@ static int wdc_get_pci_ids(nvme_root_t r, uint32_t *device_id,
nvme_ctrl_get_sysfs_dir(c));
nvme_free_ctrl(c);
} else {
- n = nvme_scan_namespace(devicename);
+ n = nvme_scan_namespace(dev->name);
if (!n) {
- fprintf(stderr, "Unable to find %s\n", devicename);
+ fprintf(stderr, "Unable to find %s\n", dev->name);
return -1;
}
@@ -1359,13 +1357,13 @@ static int wdc_get_pci_ids(nvme_root_t r, uint32_t *device_id,
return 0;
}
-static int wdc_get_vendor_id(int fd, uint32_t *vendor_id)
+static int wdc_get_vendor_id(struct nvme_dev *dev, uint32_t *vendor_id)
{
int ret;
struct nvme_id_ctrl ctrl;
memset(&ctrl, 0, sizeof(struct nvme_id_ctrl));
- ret = nvme_identify_ctrl(fd, &ctrl);
+ ret = nvme_identify_ctrl(dev_fd(dev), &ctrl);
if (ret) {
fprintf(stderr, "ERROR : WDC : nvme_identify_ctrl() failed "
"0x%x\n", ret);
@@ -1382,13 +1380,13 @@ static bool wdc_check_power_of_2(int num)
return (num && ( !(num & (num-1))));
}
-static int wdc_get_model_number(int fd, char *model)
+static int wdc_get_model_number(struct nvme_dev *dev, char *model)
{
int ret,i;
struct nvme_id_ctrl ctrl;
memset(&ctrl, 0, sizeof(struct nvme_id_ctrl));
- ret = nvme_identify_ctrl(fd, &ctrl);
+ ret = nvme_identify_ctrl(dev_fd(dev), &ctrl);
if (ret) {
fprintf(stderr, "ERROR : WDC : nvme_identify_ctrl() failed "
"0x%x\n", ret);
@@ -1404,16 +1402,16 @@ static int wdc_get_model_number(int fd, char *model)
return ret;
}
-static bool wdc_check_device(nvme_root_t r, int fd)
+static bool wdc_check_device(nvme_root_t r, struct nvme_dev *dev)
{
int ret;
bool supported;
uint32_t read_device_id = -1, read_vendor_id = -1;
- ret = wdc_get_pci_ids(r, &read_device_id, &read_vendor_id);
+ ret = wdc_get_pci_ids(r, dev, &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(fd, &read_vendor_id) < 0)
+ if (wdc_get_vendor_id(dev, &read_vendor_id) < 0)
return false;
}
@@ -1430,13 +1428,13 @@ static bool wdc_check_device(nvme_root_t r, int fd)
return supported;
}
-static bool wdc_enc_check_model(int fd)
+static bool wdc_enc_check_model(struct nvme_dev *dev)
{
int ret;
bool supported;
char model[NVME_ID_CTRL_MODEL_NUMBER_SIZE+1];
- ret = wdc_get_model_number(fd, model);
+ ret = wdc_get_model_number(dev, model);
if (ret < 0)
return false;
@@ -1450,23 +1448,24 @@ static bool wdc_enc_check_model(int fd)
return supported;
}
-static __u64 wdc_get_drive_capabilities(nvme_root_t r, int fd) {
+static __u64 wdc_get_drive_capabilities(nvme_root_t r, struct nvme_dev *dev)
+{
int ret;
uint32_t read_device_id = -1, read_vendor_id = -1;
__u64 capabilities = 0;
__u32 cust_id;
- ret = wdc_get_pci_ids(r, &read_device_id, &read_vendor_id);
+ ret = wdc_get_pci_ids(r, dev, &read_device_id, &read_vendor_id);
if (ret < 0)
{
- if (wdc_get_vendor_id(fd, &read_vendor_id) < 0)
+ if (wdc_get_vendor_id(dev, &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, fd);
+ capabilities = wdc_get_enc_drive_capabilities(r, dev);
return capabilities;
}
@@ -1484,11 +1483,13 @@ static __u64 wdc_get_drive_capabilities(nvme_root_t r, int fd) {
WDC_DRIVE_CAP_PURGE);
/* verify the 0xCA log page is supported */
- if (wdc_nvme_check_supported_log_page(r, fd, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE) == true)
+ if (wdc_nvme_check_supported_log_page(r, dev,
+ WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE))
capabilities |= WDC_DRIVE_CAP_CA_LOG_PAGE;
/* verify the 0xC1 log page is supported */
- if (wdc_nvme_check_supported_log_page(r, fd, WDC_NVME_ADD_LOG_OPCODE) == true)
+ if (wdc_nvme_check_supported_log_page(r, dev,
+ WDC_NVME_ADD_LOG_OPCODE))
capabilities |= WDC_DRIVE_CAP_C1_LOG_PAGE;
break;
default:
@@ -1504,11 +1505,14 @@ static __u64 wdc_get_drive_capabilities(nvme_root_t r, int fd) {
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, fd, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE) == true)
+ if (wdc_nvme_check_supported_log_page(r, dev,
+ WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE))
capabilities |= WDC_DRIVE_CAP_CA_LOG_PAGE;
/* verify the 0xD0 log page is supported */
- if (wdc_nvme_check_supported_log_page(r, fd, WDC_NVME_GET_VU_SMART_LOG_OPCODE) == true)
+ if (wdc_nvme_check_supported_log_page(r, dev,
+ WDC_NVME_GET_VU_SMART_LOG_OPCODE)
+ == true)
capabilities |= WDC_DRIVE_CAP_D0_LOG_PAGE;
break;
case WDC_NVME_SN640_DEV_ID:
@@ -1524,8 +1528,12 @@ static __u64 wdc_get_drive_capabilities(nvme_root_t r, int fd) {
case WDC_NVME_SN560_DEV_ID_2:
/* FALLTHRU */
case WDC_NVME_SN560_DEV_ID_3:
+ /* FALLTHRU */
+ case WDC_NVME_SN660_DEV_ID:
/* verify the 0xC0 log page is supported */
- if (wdc_nvme_check_supported_log_page(r, fd, WDC_NVME_GET_EOL_STATUS_LOG_OPCODE) == true) {
+ if (wdc_nvme_check_supported_log_page(r, dev,
+ WDC_NVME_GET_SMART_CLOUD_ATTR_LOG_ID)
+ == true) {
capabilities |= WDC_DRIVE_CAP_C0_LOG_PAGE;
}
@@ -1536,30 +1544,36 @@ static __u64 wdc_get_drive_capabilities(nvme_root_t r, int fd) {
WDC_DRIVE_CAP_LOG_PAGE_DIR);
/* verify the 0xC1 (OCP Error Recovery) log page is supported */
- if (wdc_nvme_check_supported_log_page(r, fd, WDC_ERROR_REC_LOG_ID) == true)
+ if (wdc_nvme_check_supported_log_page(r, dev,
+ WDC_ERROR_REC_LOG_ID))
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, fd, WDC_LATENCY_MON_OPCODE) == true)
+ if (wdc_nvme_check_supported_log_page(r, dev,
+ WDC_LATENCY_MON_LOG_ID))
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, fd, WDC_DEV_CAP_LOG_ID) == true)
+ if (wdc_nvme_check_supported_log_page(r, dev,
+ WDC_DEV_CAP_LOG_ID))
capabilities |= WDC_DRIVE_CAP_OCP_C4_LOG_PAGE;
/* verify the 0xC5 (OCP Unsupported Requirments) log page is supported */
- if (wdc_nvme_check_supported_log_page(r, fd, WDC_UNSUPPORTED_REQS_LOG_ID) == true)
+ if (wdc_nvme_check_supported_log_page(r, dev,
+ WDC_UNSUPPORTED_REQS_LOG_ID))
capabilities |= WDC_DRIVE_CAP_OCP_C5_LOG_PAGE;
/* verify the 0xCA log page is supported */
- if (wdc_nvme_check_supported_log_page(r, fd, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE) == true)
+ if (wdc_nvme_check_supported_log_page(r, dev,
+ WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE))
capabilities |= WDC_DRIVE_CAP_CA_LOG_PAGE;
/* verify the 0xD0 log page is supported */
- if (wdc_nvme_check_supported_log_page(r, fd, WDC_NVME_GET_VU_SMART_LOG_OPCODE) == true)
+ if (wdc_nvme_check_supported_log_page(r, dev,
+ WDC_NVME_GET_VU_SMART_LOG_OPCODE))
capabilities |= WDC_DRIVE_CAP_D0_LOG_PAGE;
- cust_id = wdc_get_fw_cust_id(r, fd);
+ cust_id = wdc_get_fw_cust_id(r, dev);
if (cust_id == WDC_INVALID_CUSTOMER_ID) {
fprintf(stderr, "%s: ERROR : WDC : invalid customer id\n", __func__);
return -1;
@@ -1579,9 +1593,9 @@ static __u64 wdc_get_drive_capabilities(nvme_root_t r, int fd) {
/* FALLTHRU */
case WDC_NVME_SN860_DEV_ID:
/* verify the 0xC0 log page is supported */
- if (wdc_nvme_check_supported_log_page(r, fd, WDC_NVME_GET_EOL_STATUS_LOG_OPCODE) == true) {
+ if (wdc_nvme_check_supported_log_page(r, dev,
+ WDC_NVME_GET_EOL_STATUS_LOG_OPCODE))
capabilities |= WDC_DRIVE_CAP_C0_LOG_PAGE;
- }
/* FALLTHRU */
case WDC_NVME_ZN540_DEV_ID:
/* FALLTHRU */
@@ -1595,11 +1609,13 @@ static __u64 wdc_get_drive_capabilities(nvme_root_t r, int fd) {
WDC_DRIVE_CAP_LOG_PAGE_DIR );
/* verify the 0xCA log page is supported */
- if (wdc_nvme_check_supported_log_page(r, fd, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE) == true)
+ if (wdc_nvme_check_supported_log_page(r, dev,
+ WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE))
capabilities |= WDC_DRIVE_CAP_CA_LOG_PAGE;
/* verify the 0xD0 log page is supported */
- if (wdc_nvme_check_supported_log_page(r, fd, WDC_NVME_GET_VU_SMART_LOG_OPCODE) == true)
+ if (wdc_nvme_check_supported_log_page(r, dev,
+ WDC_NVME_GET_VU_SMART_LOG_OPCODE))
capabilities |= WDC_DRIVE_CAP_D0_LOG_PAGE;
break;
case WDC_NVME_SN650_DEV_ID:
@@ -1610,23 +1626,45 @@ static __u64 wdc_get_drive_capabilities(nvme_root_t r, int fd) {
case WDC_NVME_SN655_DEV_ID:
case WDC_NVME_SN550_DEV_ID:
/* verify the 0xC0 log page is supported */
- if (wdc_nvme_check_supported_log_page(r, fd, WDC_NVME_GET_EOL_STATUS_LOG_OPCODE) == true) {
+ if (wdc_nvme_check_supported_log_page(r, dev,
+ WDC_NVME_GET_SMART_CLOUD_ATTR_LOG_ID))
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, WDC_ERROR_REC_LOG_ID))
+ 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, WDC_LATENCY_MON_LOG_ID))
+ 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, WDC_DEV_CAP_LOG_ID))
+ capabilities |= WDC_DRIVE_CAP_OCP_C4_LOG_PAGE;
+
+ /* verify the 0xC5 (OCP Unsupported Requirments) log page is supported */
+ if (wdc_nvme_check_supported_log_page(r, dev, WDC_UNSUPPORTED_REQS_LOG_ID))
+ capabilities |= WDC_DRIVE_CAP_OCP_C5_LOG_PAGE;
capabilities |= (WDC_DRIVE_CAP_CAP_DIAG | WDC_DRIVE_CAP_INTERNAL_LOG |
WDC_DRIVE_CAP_DRIVE_STATUS | WDC_DRIVE_CAP_CLEAR_ASSERT |
- WDC_DRIVE_CAP_RESIZE | WDC_DRIVE_CAP_CLEAR_PCIE |
- WDC_DRIVE_CAP_FW_ACTIVATE_HISTORY | WDC_DRIVE_CAP_CLEAR_FW_ACT_HISTORY |
+ WDC_DRIVE_CAP_RESIZE | WDC_DRIVE_CAP_FW_ACTIVATE_HISTORY |
WDC_DRVIE_CAP_DISABLE_CTLR_TELE_LOG | WDC_DRIVE_CAP_REASON_ID |
- WDC_DRIVE_CAP_LOG_PAGE_DIR | WDC_DRIVE_CAP_INFO |
- WDC_DRIVE_CAP_CLOUD_SSD_VERSION);
+ WDC_DRIVE_CAP_LOG_PAGE_DIR);
+
+ cust_id = wdc_get_fw_cust_id(r, dev);
+ if (cust_id == WDC_INVALID_CUSTOMER_ID) {
+ fprintf(stderr, "%s: ERROR : WDC : invalid customer id\n", __func__);
+ return -1;
+ }
+
+ if ((cust_id == WDC_CUSTOMER_ID_0x1004) || (cust_id == WDC_CUSTOMER_ID_0x1008) ||
+ (cust_id == WDC_CUSTOMER_ID_0x1005) || (cust_id == WDC_CUSTOMER_ID_0x1304))
+ capabilities |= (WDC_DRIVE_CAP_VU_FID_CLEAR_FW_ACT_HISTORY | WDC_DRIVE_CAP_VU_FID_CLEAR_PCIE |
+ WDC_DRIVE_CAP_INFO | WDC_DRIVE_CAP_CLOUD_SSD_VERSION);
+ else
+ capabilities |= (WDC_DRIVE_CAP_CLEAR_FW_ACT_HISTORY | WDC_DRIVE_CAP_CLEAR_PCIE);
- break;
- case WDC_NVME_SN730B_DEV_ID:
- /* FALLTHRU */
- case WDC_NVME_SN730B_DEV_ID_1:
- capabilities = WDC_SN730B_CAP_VUC_LOG;
break;
default:
capabilities = 0;
@@ -1685,13 +1723,15 @@ static __u64 wdc_get_drive_capabilities(nvme_root_t r, int fd) {
return capabilities;
}
-static __u64 wdc_get_enc_drive_capabilities(nvme_root_t r, int fd) {
+static __u64 wdc_get_enc_drive_capabilities(nvme_root_t r,
+ struct nvme_dev *dev)
+{
int ret;
uint32_t read_vendor_id;
__u64 capabilities = 0;
__u32 cust_id;
- ret = wdc_get_vendor_id(fd, &read_vendor_id);
+ ret = wdc_get_vendor_id(dev, &read_vendor_id);
if (ret < 0)
return capabilities;
@@ -1701,11 +1741,11 @@ static __u64 wdc_get_enc_drive_capabilities(nvme_root_t r, int fd) {
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, fd, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE) == true)
+ if (wdc_nvme_check_supported_log_page(r, dev, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE) == true)
capabilities |= WDC_DRIVE_CAP_CA_LOG_PAGE;
/* verify the 0xC1 log page is supported */
- if (wdc_nvme_check_supported_log_page(r, fd, WDC_NVME_ADD_LOG_OPCODE) == true)
+ if (wdc_nvme_check_supported_log_page(r, dev, WDC_NVME_ADD_LOG_OPCODE) == true)
capabilities |= WDC_DRIVE_CAP_C1_LOG_PAGE;
break;
case WDC_NVME_VID_2:
@@ -1714,22 +1754,22 @@ static __u64 wdc_get_enc_drive_capabilities(nvme_root_t r, int fd) {
WDC_DRIVE_CAP_RESIZE);
/* verify the 0xC3 log page is supported */
- if (wdc_nvme_check_supported_log_page(r, fd, WDC_LATENCY_MON_OPCODE) == true)
+ if (wdc_nvme_check_supported_log_page(r, dev, WDC_LATENCY_MON_LOG_ID) == true)
capabilities |= WDC_DRIVE_CAP_C3_LOG_PAGE;
/* verify the 0xCB log page is supported */
- if (wdc_nvme_check_supported_log_page(r, fd, WDC_NVME_GET_FW_ACT_HISTORY_LOG_ID) == true)
+ if (wdc_nvme_check_supported_log_page(r, dev, WDC_NVME_GET_FW_ACT_HISTORY_LOG_ID) == true)
capabilities |= WDC_DRIVE_CAP_FW_ACTIVATE_HISTORY;
/* verify the 0xCA log page is supported */
- if (wdc_nvme_check_supported_log_page(r, fd, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE) == true)
+ if (wdc_nvme_check_supported_log_page(r, dev, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE) == true)
capabilities |= WDC_DRIVE_CAP_CA_LOG_PAGE;
/* verify the 0xD0 log page is supported */
- if (wdc_nvme_check_supported_log_page(r, fd, WDC_NVME_GET_VU_SMART_LOG_OPCODE) == true)
+ if (wdc_nvme_check_supported_log_page(r, dev, WDC_NVME_GET_VU_SMART_LOG_OPCODE) == true)
capabilities |= WDC_DRIVE_CAP_D0_LOG_PAGE;
- cust_id = wdc_get_fw_cust_id(r, fd);
+ cust_id = wdc_get_fw_cust_id(r, dev);
if (cust_id == WDC_INVALID_CUSTOMER_ID) {
fprintf(stderr, "%s: ERROR : WDC : invalid customer id\n", __func__);
return -1;
@@ -1752,7 +1792,8 @@ static __u64 wdc_get_enc_drive_capabilities(nvme_root_t r, int fd) {
return capabilities;
}
-static int wdc_get_serial_name(int fd, char *file, size_t len, const char *suffix)
+static int wdc_get_serial_name(struct nvme_dev *dev, char *file, size_t len,
+ const char *suffix)
{
int i;
int ret;
@@ -1765,7 +1806,7 @@ static int wdc_get_serial_name(int fd, char *file, size_t len, const char *suffi
strncpy(orig, file, PATH_MAX - 1);
memset(file, 0, len);
memset(&ctrl, 0, sizeof (struct nvme_id_ctrl));
- ret = nvme_identify_ctrl(fd, &ctrl);
+ ret = nvme_identify_ctrl(dev_fd(dev), &ctrl);
if (ret) {
fprintf(stderr, "ERROR : WDC : nvme_identify_ctrl() failed "
"0x%x\n", ret);
@@ -1927,7 +1968,8 @@ bool wdc_get_dev_mng_log_entry(__u32 log_length,
return valid_log;
}
-static bool get_dev_mgment_cbs_data(nvme_root_t r, int fd, __u8 log_id, void **cbs_data)
+static bool get_dev_mgment_cbs_data(nvme_root_t r, struct nvme_dev *dev,
+ __u8 log_id, void **cbs_data)
{
int ret = -1;
void* data;
@@ -1940,7 +1982,7 @@ static bool get_dev_mgment_cbs_data(nvme_root_t r, int fd, __u8 log_id, void **c
*cbs_data = NULL;
__u32 device_id, read_vendor_id;
- ret = wdc_get_pci_ids(r, &device_id, &read_vendor_id);
+ ret = wdc_get_pci_ids(r, dev, &device_id, &read_vendor_id);
if(device_id == WDC_NVME_ZN350_DEV_ID || device_id == WDC_NVME_ZN350_DEV_ID_1) {
lid = WDC_NVME_GET_DEV_MGMNT_LOG_PAGE_OPCODE_C8;
uuid_ix = 0;
@@ -1956,7 +1998,7 @@ static bool get_dev_mgment_cbs_data(nvme_root_t r, int fd, __u8 log_id, void **c
/* get the log page length */
struct nvme_get_log_args args_len = {
.args_size = sizeof(args_len),
- .fd = fd,
+ .fd = dev_fd(dev),
.lid = lid,
.nsid = 0xFFFFFFFF,
.lpo = 0,
@@ -1993,7 +2035,7 @@ static bool get_dev_mgment_cbs_data(nvme_root_t r, int fd, __u8 log_id, void **c
/* get the log page data */
struct nvme_get_log_args args_data = {
.args_size = sizeof(args_data),
- .fd = fd,
+ .fd = dev_fd(dev),
.lid = lid,
.nsid = 0xFFFFFFFF,
.lpo = 0,
@@ -2034,7 +2076,7 @@ static bool get_dev_mgment_cbs_data(nvme_root_t r, int fd, __u8 log_id, void **c
/* get the log page data */
struct nvme_get_log_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.lid = lid,
.nsid = 0xFFFFFFFF,
.lpo = 0,
@@ -2072,13 +2114,15 @@ end:
return found;
}
-static bool wdc_nvme_check_supported_log_page(nvme_root_t r, int fd, __u8 log_id)
+static bool wdc_nvme_check_supported_log_page(nvme_root_t r,
+ struct nvme_dev *dev,
+ __u8 log_id)
{
int i;
bool found = false;
struct wdc_c2_cbs_data *cbs_data = NULL;
- if (get_dev_mgment_cbs_data(r, fd, WDC_C2_LOG_PAGES_SUPPORTED_ID, (void *)&cbs_data)) {
+ if (get_dev_mgment_cbs_data(r, dev, WDC_C2_LOG_PAGES_SUPPORTED_ID, (void *)&cbs_data)) {
if (cbs_data != NULL) {
for (i = 0; i < le32_to_cpu(cbs_data->length); i++) {
if (log_id == cbs_data->data[i]) {
@@ -2104,12 +2148,14 @@ static bool wdc_nvme_check_supported_log_page(nvme_root_t r, int fd, __u8 log_id
return found;
}
-static bool wdc_nvme_get_dev_status_log_data(nvme_root_t r, int fd, __le32 *ret_data,
+static bool wdc_nvme_get_dev_status_log_data(nvme_root_t r,
+ struct nvme_dev *dev,
+ __le32 *ret_data,
__u8 log_id)
{
__u32 *cbs_data = NULL;
- if (get_dev_mgment_cbs_data(r, fd, log_id, (void *)&cbs_data)) {
+ if (get_dev_mgment_cbs_data(r, dev, log_id, (void *)&cbs_data)) {
if (cbs_data != NULL) {
memcpy((void *)ret_data, (void *)cbs_data, 4);
free(cbs_data);
@@ -2122,7 +2168,7 @@ static bool wdc_nvme_get_dev_status_log_data(nvme_root_t r, int fd, __le32 *ret_
return false;
}
-static int wdc_do_clear_dump(int fd, __u8 opcode, __u32 cdw12)
+static int wdc_do_clear_dump(struct nvme_dev *dev, __u8 opcode, __u32 cdw12)
{
int ret;
struct nvme_passthru_cmd admin_cmd;
@@ -2130,7 +2176,7 @@ static int wdc_do_clear_dump(int fd, __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(fd, &admin_cmd, NULL);
+ ret = nvme_submit_admin_passthru(dev_fd(dev), &admin_cmd, NULL);
if (ret != 0) {
fprintf(stdout, "ERROR : WDC : Crash dump erase failed\n");
}
@@ -2248,7 +2294,7 @@ static __u32 wdc_dump_dui_data_v2(int fd, __u32 dataLen, __u64 offset, __u8 *dum
return ret;
}
-static int wdc_do_dump(int fd, __u32 opcode,__u32 data_len,
+static int wdc_do_dump(struct nvme_dev *dev, __u32 opcode,__u32 data_len,
__u32 cdw12, char *file, __u32 xfer_size)
{
int ret = 0;
@@ -2277,7 +2323,8 @@ static int wdc_do_dump(int fd, __u32 opcode,__u32 data_len,
admin_cmd.cdw13 = curr_data_offset;
while (curr_data_offset < data_len) {
- ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL);
+ ret = nvme_submit_admin_passthru(dev_fd(dev), &admin_cmd,
+ NULL);
if (ret != 0) {
nvme_show_status(ret);
fprintf(stderr, "%s: ERROR : WDC : Get chunk %d, size = 0x%x, offset = 0x%x, addr = 0x%lx\n",
@@ -2370,7 +2417,8 @@ static int wdc_do_dump_e6(int fd, __u32 opcode,__u32 data_len,
return ret;
}
-static int wdc_do_cap_telemetry_log(int fd, char *file, __u32 bs, int type, int data_area)
+static int wdc_do_cap_telemetry_log(struct nvme_dev *dev, char *file,
+ __u32 bs, int type, int data_area)
{
struct nvme_telemetry_log *log;
size_t full_size = 0;
@@ -2386,7 +2434,7 @@ static int wdc_do_cap_telemetry_log(int fd, char *file, __u32 bs, int type, int
nvme_root_t r;
memset(&ctrl, 0, sizeof (struct nvme_id_ctrl));
- err = nvme_identify_ctrl(fd, &ctrl);
+ err = nvme_identify_ctrl(dev_fd(dev), &ctrl);
if (err) {
fprintf(stderr, "ERROR : WDC : nvme_identify_ctrl() failed "
"0x%x\n", err);
@@ -2399,7 +2447,7 @@ static int wdc_do_cap_telemetry_log(int fd, char *file, __u32 bs, int type, int
}
r = nvme_scan(NULL);
- capabilities = wdc_get_drive_capabilities(r, fd);
+ capabilities = wdc_get_drive_capabilities(r, dev);
if (type == WDC_TELEMETRY_TYPE_HOST) {
host_gen = 1;
@@ -2407,8 +2455,9 @@ static int wdc_do_cap_telemetry_log(int fd, char *file, __u32 bs, int type, int
} 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(fd, WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID, 0,
- 4, buf, &result);
+ err = nvme_get_features_data(dev_fd(dev),
+ WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID,
+ 0, 4, buf, &result);
if (err == 0) {
if (result == 0) {
/* enabled */
@@ -2448,11 +2497,14 @@ static int wdc_do_cap_telemetry_log(int fd, char *file, __u32 bs, int type, int
}
if (ctrl_init)
- err = nvme_get_ctrl_telemetry(fd, true, &log, data_area, &full_size);
+ err = nvme_get_ctrl_telemetry(dev_fd(dev), true, &log,
+ data_area, &full_size);
else if (host_gen)
- err = nvme_get_new_host_telemetry(fd, &log, data_area, &full_size);
+ err = nvme_get_new_host_telemetry(dev_fd(dev), &log,
+ data_area, &full_size);
else
- err = nvme_get_host_telemetry(fd, &log, data_area, &full_size);
+ err = nvme_get_host_telemetry(dev_fd(dev), &log, data_area,
+ &full_size);
if (err < 0) {
perror("get-telemetry-log");
@@ -2499,7 +2551,7 @@ close_output:
return err;
}
-static int wdc_do_cap_diag(nvme_root_t r, int fd, char *file,
+static int wdc_do_cap_diag(nvme_root_t r, struct nvme_dev *dev, char *file,
__u32 xfer_size, int type, int data_area)
{
int ret = -1;
@@ -2516,7 +2568,8 @@ static int wdc_do_cap_diag(nvme_root_t r, int fd, char *file,
memset(log_hdr, 0, e6_log_hdr_size);
if (type == WDC_TELEMETRY_TYPE_NONE) {
- ret = wdc_dump_length_e6(fd, WDC_NVME_CAP_DIAG_OPCODE,
+ ret = wdc_dump_length_e6(dev_fd(dev),
+ WDC_NVME_CAP_DIAG_OPCODE,
WDC_NVME_CAP_DIAG_HEADER_TOC_SIZE>>2,
0x00,
log_hdr);
@@ -2531,7 +2584,9 @@ static int wdc_do_cap_diag(nvme_root_t r, int fd, char *file,
if (cap_diag_length == 0) {
fprintf(stderr, "INFO : WDC : Capture Diagnostics log is empty\n");
} else {
- ret = wdc_do_dump_e6(fd, WDC_NVME_CAP_DIAG_OPCODE, cap_diag_length,
+ ret = wdc_do_dump_e6(dev_fd(dev),
+ WDC_NVME_CAP_DIAG_OPCODE,
+ cap_diag_length,
(WDC_NVME_CAP_DIAG_SUBCMD << WDC_NVME_SUBCMD_SHIFT) | WDC_NVME_CAP_DIAG_CMD,
file, xfer_size, (__u8 *)log_hdr);
@@ -2540,7 +2595,7 @@ static int wdc_do_cap_diag(nvme_root_t r, int fd, 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(fd, file, xfer_size, type, data_area);
+ ret = wdc_do_cap_telemetry_log(dev, file, xfer_size, type, data_area);
} else
fprintf(stderr, "%s: ERROR : Invalid type : %d\n", __func__, type);
@@ -2932,10 +2987,11 @@ static int wdc_cap_diag(int argc, char **argv, struct command *command,
char *desc = "Capture Diagnostics Log.";
char *file = "Output file pathname.";
char *size = "Data retrieval transfer size.";
+ __u64 capabilities = 0;
char f[PATH_MAX] = {0};
+ struct nvme_dev *dev;
__u32 xfer_size = 0;
- int fd, ret = 0;
- __u64 capabilities = 0;
+ int ret = 0;
struct config {
char *file;
@@ -2953,9 +3009,9 @@ static int wdc_cap_diag(int argc, char **argv, struct command *command,
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
+ if (ret)
+ return ret;
r = nvme_scan(NULL);
@@ -2963,7 +3019,7 @@ static int wdc_cap_diag(int argc, char **argv, struct command *command,
strncpy(f, cfg.file, PATH_MAX - 1);
if (cfg.xfer_size != 0)
xfer_size = cfg.xfer_size;
- ret = wdc_get_serial_name(fd, f, PATH_MAX, "cap_diag");
+ ret = wdc_get_serial_name(dev, f, PATH_MAX, "cap_diag");
if (ret) {
fprintf(stderr, "ERROR : WDC: failed to generate file name\n");
goto out;
@@ -2977,15 +3033,15 @@ static int wdc_cap_diag(int argc, char **argv, struct command *command,
strcat(f, ".bin");
}
- capabilities = wdc_get_drive_capabilities(r, fd);
+ capabilities = wdc_get_drive_capabilities(r, dev);
if ((capabilities & WDC_DRIVE_CAP_CAP_DIAG) == WDC_DRIVE_CAP_CAP_DIAG)
- ret = wdc_do_cap_diag(r, fd, f, xfer_size, 0, 0);
+ ret = wdc_do_cap_diag(r, dev, f, xfer_size, 0, 0);
else
fprintf(stderr,
"ERROR : WDC: unsupported device for this command\n");
out:
nvme_free_tree(r);
- close(fd);
+ dev_close(dev);
return ret;
}
@@ -3232,13 +3288,14 @@ static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *command
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 fd, ret = -1;
int telemetry_type = 0, telemetry_data_area = 0;
UtilsTimeInfo timeInfo;
__u8 timeStamp[MAX_PATH_LEN];
__u64 capabilities = 0;
+ int ret = -1;
struct config {
char *file;
@@ -3271,12 +3328,12 @@ static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *command
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
+ if (ret)
+ return ret;
r = nvme_scan(NULL);
- if (!wdc_check_device(r, fd))
+ if (!wdc_check_device(r, dev))
goto out;
if (cfg.xfer_size != 0)
@@ -3305,7 +3362,7 @@ static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *command
timeInfo.hour, timeInfo.minute, timeInfo.second);
snprintf(fileSuffix, PATH_MAX, "_internal_fw_log_%s", (char*)timeStamp);
- ret = wdc_get_serial_name(fd, f, PATH_MAX, fileSuffix);
+ ret = wdc_get_serial_name(dev, f, PATH_MAX, fileSuffix);
if (ret) {
fprintf(stderr, "ERROR : WDC: failed to generate file name\n");
goto out;
@@ -3349,12 +3406,12 @@ static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *command
goto out;
}
- capabilities = wdc_get_drive_capabilities(r, fd);
+ capabilities = wdc_get_drive_capabilities(r, dev);
if ((capabilities & WDC_DRIVE_CAP_INTERNAL_LOG) == WDC_DRIVE_CAP_INTERNAL_LOG) {
if (telemetry_data_area == 0)
telemetry_data_area = 3; /* Set the default DA to 3 if not specified */
- ret = wdc_do_cap_diag(r, fd, f, xfer_size,
+ ret = wdc_do_cap_diag(r, dev, f, xfer_size,
telemetry_type, telemetry_data_area);
goto out;
}
@@ -3364,7 +3421,7 @@ static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *command
if (telemetry_data_area == 0)
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(fd, f, xfer_size,
+ ret = wdc_do_cap_telemetry_log(dev, f, xfer_size,
telemetry_type, telemetry_data_area);
goto out;
} else {
@@ -3374,7 +3431,8 @@ 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(fd, f, xfer_size, cfg.data_area,
+ ret = wdc_do_cap_dui(dev_fd(dev), f, xfer_size,
+ cfg.data_area,
cfg.verbose, cfg.file_size,
cfg.offset);
goto out;
@@ -3386,29 +3444,29 @@ static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *command
if (telemetry_data_area == 0)
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(fd, f, xfer_size,
+ ret = wdc_do_cap_telemetry_log(dev, f, xfer_size,
telemetry_type, telemetry_data_area);
goto out;
} else {
- ret = wdc_do_cap_dui(fd, f, xfer_size,
+ ret = wdc_do_cap_dui(dev_fd(dev), 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(fd, f);
+ ret = wdc_do_sn730_get_and_tar(dev_fd(dev), f);
else {
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
ret = -1;
}
out:
nvme_free_tree(r);
- close(fd);
+ dev_close(dev);
return ret;
}
-static int wdc_do_crash_dump(int fd, char *file, int type)
+static int wdc_do_crash_dump(struct nvme_dev *dev, char *file, int type)
{
int ret;
__u32 crash_dump_length;
@@ -3445,11 +3503,11 @@ static int wdc_do_crash_dump(int fd, char *file, int type)
WDC_NVME_CLEAR_CRASH_DUMP_CMD);
}
- ret = wdc_dump_length(fd,
- opcode,
- cdw10_size,
- cdw12_size,
- &crash_dump_length);
+ ret = wdc_dump_length(dev_fd(dev),
+ opcode,
+ cdw10_size,
+ cdw12_size,
+ &crash_dump_length);
if (ret == -1) {
if (type == WDC_NVME_PFAIL_DUMP_TYPE)
@@ -3466,7 +3524,7 @@ static int wdc_do_crash_dump(int fd, char *file, int type)
else
fprintf(stderr, "INFO : WDC: Crash dump is empty\n");
} else {
- ret = wdc_do_dump(fd,
+ ret = wdc_do_dump(dev,
opcode,
crash_dump_length,
cdw12,
@@ -3474,12 +3532,13 @@ static int wdc_do_crash_dump(int fd, char *file, int type)
crash_dump_length);
if (ret == 0)
- ret = wdc_do_clear_dump(fd, WDC_NVME_CLEAR_DUMP_OPCODE, cdw12_clear);
+ ret = wdc_do_clear_dump(dev, WDC_NVME_CLEAR_DUMP_OPCODE,
+ cdw12_clear);
}
return ret;
}
-static int wdc_crash_dump(int fd, char *file, int type)
+static int wdc_crash_dump(struct nvme_dev *dev, char *file, int type)
{
char f[PATH_MAX] = {0};
const char *dump_type;
@@ -3494,26 +3553,26 @@ static int wdc_crash_dump(int fd, char *file, int type)
else
dump_type = "_crash_dump";
- ret = wdc_get_serial_name(fd, f, PATH_MAX, dump_type);
+ ret = wdc_get_serial_name(dev, f, PATH_MAX, dump_type);
if (ret)
fprintf(stderr, "ERROR : WDC : failed to generate file name\n");
else
- ret = wdc_do_crash_dump(fd, f, type);
+ ret = wdc_do_crash_dump(dev, f, type);
return ret;
}
-static int wdc_do_drive_log(int fd, char *file)
+static int wdc_do_drive_log(struct nvme_dev *dev, char *file)
{
int ret;
__u8 *drive_log_data;
__u32 drive_log_length;
struct nvme_passthru_cmd admin_cmd;
- ret = wdc_dump_length(fd, 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),
- &drive_log_length);
+ ret = wdc_dump_length(dev_fd(dev), 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),
+ &drive_log_length);
if (ret == -1) {
return -1;
}
@@ -3533,7 +3592,7 @@ static int wdc_do_drive_log(int fd, 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(fd, &admin_cmd, NULL);
+ ret = nvme_submit_admin_passthru(dev_fd(dev), &admin_cmd, NULL);
nvme_show_status(ret);
if (ret == 0) {
ret = wdc_create_log_file(file, drive_log_data, drive_log_length);
@@ -3548,7 +3607,7 @@ static int wdc_drive_log(int argc, char **argv, struct command *command,
const char *desc = "Capture Drive Log.";
const char *file = "Output file pathname.";
char f[PATH_MAX] = {0};
- int fd;
+ struct nvme_dev *dev;
int ret;
nvme_root_t r;
__u64 capabilities = 0;
@@ -3565,18 +3624,18 @@ static int wdc_drive_log(int argc, char **argv, struct command *command,
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
+ if (ret)
+ return ret;
r = nvme_scan(NULL);
- if (!wdc_check_device(r, fd)) {
+ if (!wdc_check_device(r, dev)) {
nvme_free_tree(r);
- close(fd);
+ dev_close(dev);
return -1;
}
- capabilities = wdc_get_drive_capabilities(r, fd);
+ capabilities = wdc_get_drive_capabilities(r, dev);
if ((capabilities & WDC_DRIVE_CAP_DRIVE_LOG) == 0) {
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
@@ -3585,14 +3644,14 @@ static int wdc_drive_log(int argc, char **argv, struct command *command,
if (cfg.file != NULL) {
strncpy(f, cfg.file, PATH_MAX - 1);
}
- ret = wdc_get_serial_name(fd, f, PATH_MAX, "drive_log");
+ ret = wdc_get_serial_name(dev, f, PATH_MAX, "drive_log");
if (ret)
fprintf(stderr, "ERROR : WDC : failed to generate file name\n");
else
- ret = wdc_do_drive_log(fd, f);
+ ret = wdc_do_drive_log(dev, f);
}
nvme_free_tree(r);
- close(fd);
+ dev_close(dev);
return ret;
}
@@ -3601,9 +3660,10 @@ static int wdc_get_crash_dump(int argc, char **argv, struct command *command,
{
const char *desc = "Get Crash Dump.";
const char *file = "Output file pathname.";
- int fd, ret;
- nvme_root_t r;
__u64 capabilities = 0;
+ struct nvme_dev *dev;
+ nvme_root_t r;
+ int ret;
struct config {
char *file;
@@ -3618,32 +3678,32 @@ static int wdc_get_crash_dump(int argc, char **argv, struct command *command,
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
+ if (ret)
+ return ret;
r = nvme_scan(NULL);
- if (!wdc_check_device(r, fd)) {
+ if (!wdc_check_device(r, dev)) {
nvme_free_tree(r);
- close(fd);
+ dev_close(dev);
return -1;
}
- capabilities = wdc_get_drive_capabilities(r, fd);
+ capabilities = wdc_get_drive_capabilities(r, dev);
if ((capabilities & WDC_DRIVE_CAP_CRASH_DUMP) == 0) {
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
ret = -1;
} else {
- ret = wdc_crash_dump(fd, cfg.file, WDC_NVME_CRASH_DUMP_TYPE);
+ ret = wdc_crash_dump(dev, cfg.file, WDC_NVME_CRASH_DUMP_TYPE);
if (ret != 0) {
fprintf(stderr, "ERROR : WDC : failed to read crash dump\n");
}
}
nvme_free_tree(r);
- close(fd);
+ dev_close(dev);
return ret;
}
@@ -3652,13 +3712,13 @@ static int wdc_get_pfail_dump(int argc, char **argv, struct command *command,
{
char *desc = "Get Pfail Crash Dump.";
char *file = "Output file pathname.";
- int fd;
- int ret;
- nvme_root_t r;
__u64 capabilities = 0;
+ struct nvme_dev *dev;
struct config {
char *file;
};
+ nvme_root_t r;
+ int ret;
struct config cfg = {
.file = NULL,
@@ -3669,30 +3729,30 @@ static int wdc_get_pfail_dump(int argc, char **argv, struct command *command,
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
+ if (ret)
+ return ret;
r = nvme_scan(NULL);
- if (!wdc_check_device(r, fd)) {
+ if (!wdc_check_device(r, dev)) {
nvme_free_tree(r);
- close(fd);
+ dev_close(dev);
return -1;
}
- capabilities = wdc_get_drive_capabilities(r, fd);
+ capabilities = wdc_get_drive_capabilities(r, dev);
if ((capabilities & WDC_DRIVE_CAP_PFAIL_DUMP) == 0) {
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
ret = -1;
} else {
- ret = wdc_crash_dump(fd, cfg.file, WDC_NVME_PFAIL_DUMP_TYPE);
+ ret = wdc_crash_dump(dev, cfg.file, WDC_NVME_PFAIL_DUMP_TYPE);
if (ret != 0) {
fprintf(stderr, "ERROR : WDC : failed to read pfail crash dump\n");
}
}
nvme_free_tree(r);
- close(fd);
+ dev_close(dev);
return ret;
}
@@ -3748,29 +3808,30 @@ static int wdc_purge(int argc, char **argv,
struct command *command, struct plugin *plugin)
{
const char *desc = "Send a Purge command.";
- char *err_str;
- int fd, ret;
- nvme_root_t r;
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()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
+ if (ret)
+ return ret;
r = nvme_scan(NULL);
- if (!wdc_check_device(r, fd)) {
+ if (!wdc_check_device(r, dev)) {
nvme_free_tree(r);
- close(fd);
+ dev_close(dev);
return -1;
}
- capabilities = wdc_get_drive_capabilities(r, fd);
+ capabilities = wdc_get_drive_capabilities(r, dev);
if((capabilities & WDC_DRIVE_CAP_PURGE) == 0) {
ret = -1;
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
@@ -3779,7 +3840,8 @@ 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(fd, &admin_cmd, NULL);
+ ret = nvme_submit_admin_passthru(dev_fd(dev), &admin_cmd,
+ NULL);
if (ret > 0) {
switch (ret) {
case WDC_NVME_PURGE_CMD_SEQ_ERR:
@@ -3798,7 +3860,7 @@ static int wdc_purge(int argc, char **argv,
nvme_show_status(ret);
}
nvme_free_tree(r);
- close(fd);
+ dev_close(dev);
return ret;
}
@@ -3806,30 +3868,31 @@ static int wdc_purge_monitor(int argc, char **argv,
struct command *command, struct plugin *plugin)
{
const char *desc = "Send a Purge Monitor command.";
- int fd, ret;
- nvme_root_t r;
__u8 output[WDC_NVME_PURGE_MONITOR_DATA_LEN];
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()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
+ if (ret)
+ return ret;
r = nvme_scan(NULL);
- if (!wdc_check_device(r, fd)) {
+ if (!wdc_check_device(r, dev)) {
nvme_free_tree(r);
- close(fd);
+ dev_close(dev);
return -1;
}
- capabilities = wdc_get_drive_capabilities(r, fd);
+ capabilities = wdc_get_drive_capabilities(r, dev);
if((capabilities & WDC_DRIVE_CAP_PURGE) == 0) {
ret = -1;
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
@@ -3842,7 +3905,8 @@ 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(fd, &admin_cmd, NULL);
+ ret = nvme_submit_admin_passthru(dev_fd(dev), &admin_cmd,
+ NULL);
if (ret == 0) {
mon = (struct wdc_nvme_purge_monitor_data *) output;
printf("Purge state = 0x%0x\n", admin_cmd.result);
@@ -3858,7 +3922,7 @@ static int wdc_purge_monitor(int argc, char **argv,
nvme_show_status(ret);
}
nvme_free_tree(r);
- close(fd);
+ dev_close(dev);
return ret;
}
@@ -4009,15 +4073,16 @@ static int wdc_convert_ts(time_t time, char *ts_buf)
return 0;
}
-static int wdc_print_latency_monitor_log_normal(int fd, struct wdc_ssd_latency_monitor_log *log_data)
+static int wdc_print_latency_monitor_log_normal(struct nvme_dev *dev,
+ struct wdc_ssd_latency_monitor_log *log_data)
{
printf("Latency Monitor/C3 Log Page Data \n");
- printf(" Controller : %s\n", devicename);
+ printf(" Controller : %s\n", dev->name);
int err = -1, i, j;
struct nvme_id_ctrl ctrl;
char ts_buf[128];
- err = nvme_identify_ctrl(fd, &ctrl);
+ err = nvme_identify_ctrl(dev_fd(dev), &ctrl);
if (!err)
printf(" Serial Number: %-.*s\n", (int)sizeof(ctrl.sn), ctrl.sn);
else {
@@ -4164,14 +4229,16 @@ static void wdc_print_error_rec_log_normal(struct wdc_ocp_c1_error_recovery_log
printf(" Panic Reset Wait Time : 0x%x \n", le16_to_cpu(log_data->panic_reset_wait_time));
printf(" Panic Reset Action : 0x%x \n", log_data->panic_reset_action);
printf(" Device Recovery Action 1 : 0x%x \n", log_data->dev_recovery_action1);
- printf(" Panic ID : 0x%lx \n", le64_to_cpu(log_data->panic_id));
+ printf(" Panic ID : 0x%" PRIu64 "\n", le64_to_cpu(log_data->panic_id));
printf(" Device Capabilities : 0x%x \n", le32_to_cpu(log_data->dev_capabilities));
printf(" Vendor Specific Recovery Opcode : 0x%x \n", log_data->vs_recovery_opc);
printf(" Vendor Specific Command CDW12 : 0x%x \n", le32_to_cpu(log_data->vs_cmd_cdw12));
printf(" Vendor Specific Command CDW13 : 0x%x \n", le32_to_cpu(log_data->vs_cmd_cdw13));
- printf(" Vendor Specific Command Timeout : 0x%x \n", log_data->vs_cmd_to);
- printf(" Device Recovery Action 2 : 0x%x \n", log_data->dev_recovery_action2);
- printf(" Device Recovery Action 2 Timeout : 0x%x \n", log_data->dev_recovery_action2_to);
+ if (le16_to_cpu(log_data->log_page_version) == WDC_ERROR_REC_LOG_VERSION2) {
+ printf(" Vendor Specific Command Timeout : 0x%x \n", log_data->vs_cmd_to);
+ printf(" Device Recovery Action 2 : 0x%x \n", log_data->dev_recovery_action2);
+ printf(" Device Recovery Action 2 Timeout : 0x%x \n", log_data->dev_recovery_action2_to);
+ }
printf(" Log Page Version : 0x%x \n", le16_to_cpu(log_data->log_page_version));
printf(" Log page GUID : 0x");
for (j = 0; j < WDC_OCP_C1_GUID_LENGTH; j++) {
@@ -4193,9 +4260,11 @@ static void wdc_print_error_rec_log_json(struct wdc_ocp_c1_error_recovery_log *l
json_object_add_value_int(root, "Vendor Specific Recovery Opcode", log_data->vs_recovery_opc);
json_object_add_value_int(root, "Vendor Specific Command CDW12", le32_to_cpu(log_data->vs_cmd_cdw12));
json_object_add_value_int(root, "Vendor Specific Command CDW13", le32_to_cpu(log_data->vs_cmd_cdw13));
- json_object_add_value_int(root, "Vendor Specific Command Timeout", log_data->vs_cmd_to);
- json_object_add_value_int(root, "Device Recovery Action 2", log_data->dev_recovery_action2);
- json_object_add_value_int(root, "Device Recovery Action 2 Timeout", log_data->dev_recovery_action2_to);
+ if (le16_to_cpu(log_data->log_page_version) == WDC_ERROR_REC_LOG_VERSION2) {
+ json_object_add_value_int(root, "Vendor Specific Command Timeout", log_data->vs_cmd_to);
+ json_object_add_value_int(root, "Device Recovery Action 2", log_data->dev_recovery_action2);
+ json_object_add_value_int(root, "Device Recovery Action 2 Timeout", log_data->dev_recovery_action2_to);
+ }
json_object_add_value_int(root, "Log Page Version", le16_to_cpu(log_data->log_page_version));
char guid[40];
@@ -4442,7 +4511,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(void *data)
+static void wdc_print_bd_ca_log_normal(struct nvme_dev *dev, void *data)
{
struct wdc_bd_ca_log_format *bd_data = (struct wdc_bd_ca_log_format *)data;
__u64 *raw;
@@ -4453,7 +4522,7 @@ static void wdc_print_bd_ca_log_normal(void *data)
if (bd_data->field_id == 0x00) {
raw = (__u64*)&bd_data->raw_value[0];
printf("Additional Smart Log for NVME device:%s namespace-id:%x\n",
- devicename, WDC_DE_GLOBAL_NSID);
+ dev->name, WDC_DE_GLOBAL_NSID);
printf("key normalized raw\n");
printf("program_fail_count : %3"PRIu8"%% %"PRIu64"\n",
bd_data->normalized_value, le64_to_cpu(*raw & 0x00FFFFFFFFFFFFFF));
@@ -5056,7 +5125,7 @@ static void wdc_print_fw_act_history_log_json(__u8 *data, int num_entries, __u32
root = json_create_object();
- if(data[0] == WDC_NVME_GET_FW_ACT_HISTORY_C2_LOG_ID) {
+ if (data[0] == WDC_NVME_GET_FW_ACT_HISTORY_C2_LOG_ID) {
struct wdc_fw_act_history_log_format_c2 *fw_act_history_entry = (struct wdc_fw_act_history_log_format_c2 *)(data);
oldestEntryIdx = WDC_MAX_NUM_ACT_HIST_ENTRIES;
@@ -5100,7 +5169,7 @@ static void wdc_print_fw_act_history_log_json(__u8 *data, int num_entries, __u32
json_object_add_value_string(root, "Power on Hour", time_str);
} else {
uint64_t timestamp = (0x0000FFFFFFFFFFFF & le64_to_cpu(fw_act_history_entry->entry[entryIdx].timestamp));
- json_object_add_value_int(root, "Timestamp", timestamp);
+ json_object_add_value_uint64(root, "Timestamp", timestamp);
}
json_object_add_value_int(root, "Power Cycle Count",
@@ -5122,6 +5191,9 @@ static void wdc_print_fw_act_history_log_json(__u8 *data, int num_entries, __u32
json_object_add_value_string(root, "Result", fail_str);
}
+ json_print_object(root, NULL);
+ printf("\n");
+
entryIdx++;
if (entryIdx >= WDC_MAX_NUM_ACT_HIST_ENTRIES)
entryIdx = 0;
@@ -5179,15 +5251,15 @@ static void wdc_print_fw_act_history_log_json(__u8 *data, int num_entries, __u32
json_object_add_value_string(root, "Result", fail_str);
}
+ json_print_object(root, NULL);
+ printf("\n");
+
entryIdx++;
if (entryIdx >= WDC_MAX_NUM_ACT_HIST_ENTRIES)
entryIdx = 0;
}
}
- json_print_object(root, NULL);
- printf("\n");
-
json_free_object(root);
}
@@ -5205,7 +5277,7 @@ static int nvme_get_ext_smart_cloud_log(int fd, __u8 **data, int uuid_index, __u
struct nvme_get_log_args args = {
.args_size = sizeof(args),
.fd = fd,
- .lid = WDC_NVME_GET_EOL_STATUS_LOG_OPCODE,
+ .lid = WDC_NVME_GET_SMART_CLOUD_ATTR_LOG_ID,
.nsid = namespace_id,
.lpo = 0,
.lsp = NVME_LOG_LSP_NONE,
@@ -5626,10 +5698,12 @@ static void wdc_print_ext_smart_cloud_log_normal(void *data, int mask)
else
printf(" SMART Cloud Attributes :- \n");
- printf(" Physical Media Units Written TLC (Bytes) : %'.0Lf\n",
- int128_to_double(ext_smart_log_ptr->ext_smart_pmuwt));
- printf(" Physical Media Units Written SLC (Bytes) : %'.0Lf\n",
- int128_to_double(ext_smart_log_ptr->ext_smart_pmuws));
+ printf(" Physical Media Units Written TLC (Bytes) : %s\n",
+ uint128_t_to_string(le128_to_cpu(
+ ext_smart_log_ptr->ext_smart_pmuwt)));
+ printf(" Physical Media Units Written SLC (Bytes) : %s\n",
+ uint128_t_to_string(le128_to_cpu(
+ ext_smart_log_ptr->ext_smart_pmuws)));
printf(" Bad User NAND Block Count (Normalized) (Int) : %d\n",
le16_to_cpu(*(uint16_t *)ext_smart_log_ptr->ext_smart_bunbc));
printf(" Bad User NAND Block Count (Raw) (Int) : %"PRIu64"\n",
@@ -5677,8 +5751,9 @@ static void wdc_print_ext_smart_cloud_log_normal(void *data, int mask)
le64_to_cpu(ext_smart_log_ptr->ext_smart_svn));
printf(" %% Free Blocks (System) (Int) : %d %%\n",
ext_smart_log_ptr->ext_smart_pfbs);
- printf(" NVMe Stats (# Data Set Management/TRIM Commands Completed) (Int) : %'.0Lf\n",
- int128_to_double(ext_smart_log_ptr->ext_smart_dcc));
+ printf(" NVMe Stats (# Data Set Management/TRIM Commands Completed) (Int) : %s\n",
+ uint128_t_to_string(le128_to_cpu(
+ ext_smart_log_ptr->ext_smart_dcc)));
printf(" Total Namespace Utilization (nvme0n1 NUSE) (Bytes) : %"PRIu64"\n",
le64_to_cpu(ext_smart_log_ptr->ext_smart_tnu));
printf(" NVMe Stats (# NVMe Format Commands Completed) (Int) : %d\n",
@@ -5696,16 +5771,18 @@ static void wdc_print_ext_smart_cloud_log_normal(void *data, int mask)
le16_to_cpu(*(uint16_t *)ext_smart_log_ptr->ext_smart_bsnbc));
printf(" Bad System NAND Block Count (Raw) (Int) : %"PRIu64"\n",
le64_to_cpu(*(uint64_t *)ext_smart_log_ptr->ext_smart_bsnbc & 0xFFFFFFFFFFFF0000));
- printf(" Endurance Estimate (Total Writable Lifetime Bytes) (Bytes) : %'.0Lf\n",
- int128_to_double(ext_smart_log_ptr->ext_smart_eest));
+ printf(" Endurance Estimate (Total Writable Lifetime Bytes) (Bytes) : %s\n",
+ uint128_t_to_string(
+ le128_to_cpu(ext_smart_log_ptr->ext_smart_eest)));
if (mask == WDC_SCA_V1_ALL) {
printf(" Thermal Throttling Status & Count (Number of thermal throttling events) (Int) : %d\n",
le16_to_cpu(ext_smart_log_ptr->ext_smart_ttc));
printf(" Total # Unaligned I/O (Int) : %"PRIu64"\n",
le64_to_cpu(ext_smart_log_ptr->ext_smart_uio));
}
- printf(" Total Physical Media Units Read (Bytes) (Int) : %'.0Lf\n",
- int128_to_double(ext_smart_log_ptr->ext_smart_pmur));
+ printf(" Total Physical Media Units Read (Bytes) (Int) : %s\n",
+ uint128_t_to_string(
+ le128_to_cpu(ext_smart_log_ptr->ext_smart_pmur)));
if (mask == WDC_SCA_V1_ALL) {
printf(" Command Timeout (# of READ Commands > 5 Seconds) (Int) : %"PRIu32"\n",
le32_to_cpu(ext_smart_log_ptr->ext_smart_rtoc));
@@ -5746,10 +5823,10 @@ static void wdc_print_ext_smart_cloud_log_json(void *data, int mask)
struct json_object *root;
root = json_create_object();
- json_object_add_value_double(root, "physical_media_units_bytes_tlc",
- int128_to_double(ext_smart_log_ptr->ext_smart_pmuwt));
- json_object_add_value_double(root, "physical_media_units_bytes_slc",
- int128_to_double(ext_smart_log_ptr->ext_smart_pmuws));
+ json_object_add_value_uint128(root, "physical_media_units_bytes_tlc",
+ le128_to_cpu(ext_smart_log_ptr->ext_smart_pmuwt));
+ json_object_add_value_uint128(root, "physical_media_units_bytes_slc",
+ le128_to_cpu(ext_smart_log_ptr->ext_smart_pmuws));
json_object_add_value_uint(root, "bad_user_blocks_normalized",
le16_to_cpu(*(uint16_t *)ext_smart_log_ptr->ext_smart_bunbc));
json_object_add_value_uint64(root, "bad_user_blocks_raw",
@@ -5797,8 +5874,8 @@ static void wdc_print_ext_smart_cloud_log_json(void *data, int mask)
le64_to_cpu(ext_smart_log_ptr->ext_smart_svn));
json_object_add_value_uint(root, "pct_free_blocks_system",
(__u8)ext_smart_log_ptr->ext_smart_pfbs);
- json_object_add_value_double(root, "num_of_trim_commands",
- int128_to_double(ext_smart_log_ptr->ext_smart_dcc));
+ json_object_add_value_uint128(root, "num_of_trim_commands",
+ le128_to_cpu(ext_smart_log_ptr->ext_smart_dcc));
json_object_add_value_uint64(root, "total_nuse_bytes",
le64_to_cpu(ext_smart_log_ptr->ext_smart_tnu));
json_object_add_value_uint(root, "num_of_format_commands",
@@ -5816,16 +5893,16 @@ static void wdc_print_ext_smart_cloud_log_json(void *data, int mask)
le16_to_cpu(*(uint16_t *)ext_smart_log_ptr->ext_smart_bsnbc));
json_object_add_value_uint64(root, "bad_system_block_raw",
le64_to_cpu(*(uint64_t *)ext_smart_log_ptr->ext_smart_bsnbc & 0xFFFFFFFFFFFF0000));
- json_object_add_value_double(root, "endurance_est_bytes",
- int128_to_double(ext_smart_log_ptr->ext_smart_eest));
+ json_object_add_value_uint128(root, "endurance_est_bytes",
+ le128_to_cpu(ext_smart_log_ptr->ext_smart_eest));
if (mask == WDC_SCA_V1_ALL) {
json_object_add_value_uint(root, "num_throttling_events",
le16_to_cpu(ext_smart_log_ptr->ext_smart_ttc));
json_object_add_value_uint64(root, "total_unaligned_io",
le64_to_cpu(ext_smart_log_ptr->ext_smart_uio));
}
- json_object_add_value_double(root, "physical_media_units_read_bytes",
- int128_to_double(ext_smart_log_ptr->ext_smart_pmur));
+ json_object_add_value_uint128(root, "physical_media_units_read_bytes",
+ le128_to_cpu(ext_smart_log_ptr->ext_smart_pmur));
if (mask == WDC_SCA_V1_ALL) {
json_object_add_value_uint(root, "num_read_timeouts",
le32_to_cpu(ext_smart_log_ptr->ext_smart_rtoc));
@@ -5874,8 +5951,10 @@ static void wdc_print_smart_cloud_attr_C0_normal(void *data)
printf(" SMART Cloud Attributes :- \n");
- printf(" Physical media units written : %'.0Lf\n", int128_to_double(&log_data[SCAO_PMUW]));
- printf(" Physical media units read : %'.0Lf\n", int128_to_double(&log_data[SCAO_PMUR]));
+ printf(" Physical media units written : %s\n",
+ uint128_t_to_string(le128_to_cpu(&log_data[SCAO_PMUW])));
+ printf(" Physical media units read : %s\n",
+ uint128_t_to_string(le128_to_cpu(&log_data[SCAO_PMUR])));
printf(" Bad user nand blocks Raw : %"PRIu64"\n",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_BUNBR] & 0x0000FFFFFFFFFFFF));
printf(" Bad user nand blocks Normalized : %d\n",
@@ -5916,8 +5995,10 @@ static void wdc_print_smart_cloud_attr_C0_normal(void *data)
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_SVN]));
printf(" NUSE Namespace utilization : %"PRIu64"\n",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_NUSE]));
- printf(" PLP start count : %'.0Lf\n", int128_to_double(&log_data[SCAO_PSC]));
- printf(" Endurance estimate : %'.0Lf\n", int128_to_double(&log_data[SCAO_EEST]));
+ printf(" PLP start count : %s\n",
+ uint128_t_to_string(le128_to_cpu(&log_data[SCAO_PSC])));
+ printf(" Endurance estimate : %s\n",
+ uint128_t_to_string(le128_to_cpu(&log_data[SCAO_EEST])));
smart_log_ver = (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_LPV]);
printf(" Log page version : %"PRIu16"\n",smart_log_ver);
printf(" Log page GUID : 0x");
@@ -5951,10 +6032,10 @@ static void wdc_print_smart_cloud_attr_C0_json(void *data)
uint16_t smart_log_ver = 0;
root = json_create_object();
- json_object_add_value_double(root, "Physical media units written",
- int128_to_double(&log_data[SCAO_PMUW]));
- json_object_add_value_double(root, "Physical media units read",
- int128_to_double(&log_data[SCAO_PMUR]));
+ json_object_add_value_uint128(root, "Physical media units written",
+ le128_to_cpu(&log_data[SCAO_PMUW]));
+ json_object_add_value_uint128(root, "Physical media units read",
+ le128_to_cpu(&log_data[SCAO_PMUR]));
json_object_add_value_uint64(root, "Bad user nand blocks - Raw",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_BUNBR] & 0x0000FFFFFFFFFFFF));
json_object_add_value_uint(root, "Bad user nand blocks - Normalized",
@@ -5999,10 +6080,10 @@ static void wdc_print_smart_cloud_attr_C0_json(void *data)
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_SVN]));
json_object_add_value_uint64(root, "NUSE - Namespace utilization",
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_NUSE]));
- json_object_add_value_double(root, "PLP start count",
- int128_to_double(&log_data[SCAO_PSC]));
- json_object_add_value_double(root, "Endurance estimate",
- int128_to_double(&log_data[SCAO_EEST]));
+ json_object_add_value_uint128(root, "PLP start count",
+ le128_to_cpu(&log_data[SCAO_PSC]));
+ json_object_add_value_uint128(root, "Endurance estimate",
+ le128_to_cpu(&log_data[SCAO_EEST]));
smart_log_ver = (uint16_t)le16_to_cpu(*(uint16_t *)&log_data[SCAO_LPV]);
json_object_add_value_uint(root, "Log page version", smart_log_ver);
char guid[40];
@@ -6135,7 +6216,7 @@ static int wdc_print_c0_eol_log(void *data, int fmt)
return 0;
}
-static int wdc_get_c0_log_page(nvme_root_t r, int fd, char *format,
+static int wdc_get_c0_log_page(nvme_root_t r, struct nvme_dev *dev, char *format,
int uuid_index, __u32 namespace_id)
{
int ret = 0;
@@ -6145,7 +6226,7 @@ static int wdc_get_c0_log_page(nvme_root_t r, int fd, char *format,
__u32 cust_id;
uint32_t device_id, read_vendor_id;
- if (!wdc_check_device(r, fd))
+ if (!wdc_check_device(r, dev))
return -1;
fmt = validate_output_format(format);
if (fmt < 0) {
@@ -6153,7 +6234,7 @@ static int wdc_get_c0_log_page(nvme_root_t r, int fd, char *format,
return fmt;
}
- ret = wdc_get_pci_ids(r, &device_id, &read_vendor_id);
+ ret = wdc_get_pci_ids(r, dev, &device_id, &read_vendor_id);
switch (device_id) {
@@ -6173,7 +6254,8 @@ static int wdc_get_c0_log_page(nvme_root_t r, int fd, char *format,
case WDC_NVME_SN560_DEV_ID_1:
case WDC_NVME_SN560_DEV_ID_2:
case WDC_NVME_SN560_DEV_ID_3:
- cust_id = wdc_get_fw_cust_id(r, fd);
+ case WDC_NVME_SN550_DEV_ID:
+ cust_id = wdc_get_fw_cust_id(r, dev);
if (cust_id == WDC_INVALID_CUSTOMER_ID) {
fprintf(stderr, "%s: ERROR : WDC : invalid customer id\n", __func__);
return -1;
@@ -6189,7 +6271,8 @@ static int wdc_get_c0_log_page(nvme_root_t r, int fd, char *format,
}
if (namespace_id == NVME_NSID_ALL) {
- ret = nvme_get_nsid(fd, &namespace_id);
+ ret = nvme_get_nsid(dev_fd(dev),
+ &namespace_id);
if (ret < 0) {
namespace_id = NVME_NSID_ALL;
}
@@ -6198,8 +6281,8 @@ static int wdc_get_c0_log_page(nvme_root_t r, int fd, char *format,
/* 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,
+ .fd = dev_fd(dev),
+ .lid = WDC_NVME_GET_SMART_CLOUD_ATTR_LOG_ID,
.nsid = namespace_id,
.lpo = 0,
.lsp = NVME_LOG_LSP_NONE,
@@ -6261,7 +6344,7 @@ static int wdc_get_c0_log_page(nvme_root_t r, int fd, char *format,
/* Get the 0xC0 log data */
struct nvme_get_log_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.lid = WDC_NVME_GET_EOL_STATUS_LOG_OPCODE,
.nsid = NVME_NSID_ALL,
.lpo = 0,
@@ -6302,8 +6385,10 @@ static int wdc_get_c0_log_page(nvme_root_t r, int fd, char *format,
}
/* Get the 0xC0 log data */
- ret = nvme_get_log_simple(fd, WDC_NVME_GET_EOL_STATUS_LOG_OPCODE,
- WDC_NVME_EOL_STATUS_LOG_LEN, data);
+ ret = nvme_get_log_simple(dev_fd(dev),
+ WDC_NVME_GET_EOL_STATUS_LOG_OPCODE,
+ WDC_NVME_EOL_STATUS_LOG_LEN,
+ data);
if (strcmp(format, "json"))
nvme_show_status(ret);
@@ -6328,8 +6413,9 @@ static int wdc_get_c0_log_page(nvme_root_t r, int fd, char *format,
}
/* Get the 0xC0 log data */
- ret = nvme_get_log_simple(fd, WDC_NVME_GET_SMART_CLOUD_ATTR_LOG_OPCODE,
- WDC_NVME_SMART_CLOUD_ATTR_LEN, data);
+ ret = nvme_get_log_simple(dev_fd(dev),
+ WDC_NVME_GET_SMART_CLOUD_ATTR_LOG_ID,
+ WDC_NVME_SMART_CLOUD_ATTR_LEN, data);
if (strcmp(format, "json"))
nvme_show_status(ret);
@@ -6348,7 +6434,8 @@ static int wdc_get_c0_log_page(nvme_root_t r, int fd, 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(fd, &data, uuid_index, namespace_id);
+ ret = nvme_get_ext_smart_cloud_log(dev_fd(dev), &data,
+ uuid_index, namespace_id);
if (strcmp(format, "json"))
nvme_show_status(ret);
@@ -6375,7 +6462,9 @@ static int wdc_get_c0_log_page(nvme_root_t r, int fd, char *format,
return ret;
}
-static int wdc_print_latency_monitor_log(int fd, struct wdc_ssd_latency_monitor_log *log_data, int fmt)
+static int wdc_print_latency_monitor_log(struct nvme_dev *dev,
+ struct wdc_ssd_latency_monitor_log *log_data,
+ int fmt)
{
if (!log_data) {
fprintf(stderr, "ERROR : WDC : Invalid C3 log data buffer\n");
@@ -6383,7 +6472,7 @@ static int wdc_print_latency_monitor_log(int fd, struct wdc_ssd_latency_monitor_
}
switch (fmt) {
case NORMAL:
- wdc_print_latency_monitor_log_normal(fd, log_data);
+ wdc_print_latency_monitor_log_normal(dev, log_data);
break;
case JSON:
wdc_print_latency_monitor_log_json(log_data);
@@ -6460,7 +6549,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(void *bd_data, int fmt)
+static int wdc_print_bd_ca_log(struct nvme_dev *dev, void *bd_data, int fmt)
{
if (!bd_data) {
fprintf(stderr, "ERROR : WDC : Invalid buffer to read data\n");
@@ -6468,7 +6557,7 @@ static int wdc_print_bd_ca_log(void *bd_data, int fmt)
}
switch (fmt) {
case NORMAL:
- wdc_print_bd_ca_log_normal(bd_data);
+ wdc_print_bd_ca_log_normal(dev, bd_data);
break;
case JSON:
wdc_print_bd_ca_log_json(bd_data);
@@ -6515,7 +6604,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, int fd, char *format)
+static int wdc_get_ca_log_page(nvme_root_t r, struct nvme_dev *dev, char *format)
{
int ret = 0;
int fmt = -1;
@@ -6524,7 +6613,7 @@ static int wdc_get_ca_log_page(nvme_root_t r, int fd, char *format)
uint32_t read_device_id, read_vendor_id;
__u32 cust_id;
- if (!wdc_check_device(r, fd))
+ if (!wdc_check_device(r, dev))
return -1;
fmt = validate_output_format(format);
if (fmt < 0) {
@@ -6533,19 +6622,19 @@ static int wdc_get_ca_log_page(nvme_root_t r, int fd, char *format)
}
/* verify the 0xCA log page is supported */
- if (wdc_nvme_check_supported_log_page(r, fd, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE) == false) {
+ if (wdc_nvme_check_supported_log_page(r, dev, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE) == 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, fd);
+ cust_id = wdc_get_fw_cust_id(r, dev);
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, &read_device_id, &read_vendor_id);
+ ret = wdc_get_pci_ids(r, dev, &read_device_id, &read_vendor_id);
switch (read_device_id) {
@@ -6560,8 +6649,9 @@ static int wdc_get_ca_log_page(nvme_root_t r, int fd, char *format)
memset(data, 0, sizeof (__u8) * WDC_FB_CA_LOG_BUF_LEN);
- ret = nvme_get_log_simple(fd, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE,
- WDC_FB_CA_LOG_BUF_LEN, data);
+ ret = nvme_get_log_simple(dev_fd(dev),
+ WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE,
+ WDC_FB_CA_LOG_BUF_LEN, data);
if (strcmp(format, "json"))
nvme_show_status(ret);
@@ -6596,8 +6686,9 @@ static int wdc_get_ca_log_page(nvme_root_t r, int fd, char *format)
memset(data, 0, sizeof (__u8) * WDC_FB_CA_LOG_BUF_LEN);
- ret = nvme_get_log_simple(fd, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE,
- WDC_FB_CA_LOG_BUF_LEN, data);
+ ret = nvme_get_log_simple(dev_fd(dev),
+ WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE,
+ WDC_FB_CA_LOG_BUF_LEN, data);
if (strcmp(format, "json"))
nvme_show_status(ret);
@@ -6617,14 +6708,15 @@ static int wdc_get_ca_log_page(nvme_root_t r, int fd, char *format)
}
memset(data, 0, sizeof (__u8) * WDC_BD_CA_LOG_BUF_LEN);
- ret = nvme_get_log_simple(fd, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE,
- WDC_BD_CA_LOG_BUF_LEN, data);
+ ret = nvme_get_log_simple(dev_fd(dev),
+ WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE,
+ WDC_BD_CA_LOG_BUF_LEN, data);
if (strcmp(format, "json"))
nvme_show_status(ret);
if (ret == 0) {
/* parse the data */
- ret = wdc_print_bd_ca_log(data, fmt);
+ ret = wdc_print_bd_ca_log(dev, data, fmt);
} else {
fprintf(stderr, "ERROR : WDC : Unable to read CA Log Page data\n");
ret = -1;
@@ -6649,7 +6741,7 @@ static int wdc_get_ca_log_page(nvme_root_t r, int fd, char *format)
return ret;
}
-static int wdc_get_c1_log_page(nvme_root_t r, int fd,
+static int wdc_get_c1_log_page(nvme_root_t r, struct nvme_dev *dev,
char *format, uint8_t interval)
{
int ret = 0;
@@ -6663,7 +6755,7 @@ static int wdc_get_c1_log_page(nvme_root_t r, int fd,
struct wdc_log_page_subpage_header *sph;
struct wdc_ssd_perf_stats *perf;
- if (!wdc_check_device(r, fd))
+ if (!wdc_check_device(r, dev))
return -1;
fmt = validate_output_format(format);
if (fmt < 0) {
@@ -6682,8 +6774,8 @@ static int wdc_get_c1_log_page(nvme_root_t r, int fd,
}
memset(data, 0, sizeof (__u8) * WDC_ADD_LOG_BUF_LEN);
- ret = nvme_get_log_simple(fd, WDC_NVME_ADD_LOG_OPCODE,
- WDC_ADD_LOG_BUF_LEN, data);
+ ret = nvme_get_log_simple(dev_fd(dev), WDC_NVME_ADD_LOG_OPCODE,
+ WDC_ADD_LOG_BUF_LEN, data);
if (strcmp(format, "json"))
nvme_show_status(ret);
if (ret == 0) {
@@ -6708,7 +6800,7 @@ static int wdc_get_c1_log_page(nvme_root_t r, int fd,
return ret;
}
-static int wdc_get_c3_log_page(nvme_root_t r, int fd, char *format)
+static int wdc_get_c3_log_page(nvme_root_t r, struct nvme_dev *dev, char *format)
{
int ret = 0;
int fmt = -1;
@@ -6716,7 +6808,7 @@ static int wdc_get_c3_log_page(nvme_root_t r, int fd, char *format)
int i;
struct wdc_ssd_latency_monitor_log *log_data;
- if (!wdc_check_device(r, fd))
+ if (!wdc_check_device(r, dev))
return -1;
fmt = validate_output_format(format);
if (fmt < 0) {
@@ -6730,7 +6822,7 @@ static int wdc_get_c3_log_page(nvme_root_t r, int fd, char *format)
}
memset(data, 0, sizeof (__u8) * WDC_LATENCY_MON_LOG_BUF_LEN);
- ret = nvme_get_log_simple(fd, WDC_LATENCY_MON_OPCODE,
+ ret = nvme_get_log_simple(dev_fd(dev), WDC_LATENCY_MON_LOG_ID,
WDC_LATENCY_MON_LOG_BUF_LEN, data);
if (strcmp(format, "json"))
@@ -6768,7 +6860,7 @@ static int wdc_get_c3_log_page(nvme_root_t r, int fd, char *format)
}
/* parse the data */
- wdc_print_latency_monitor_log(fd, log_data, fmt);
+ wdc_print_latency_monitor_log(dev, log_data, fmt);
} else {
fprintf(stderr, "ERROR : WDC : Unable to read C3 data from buffer\n");
}
@@ -6779,7 +6871,7 @@ out:
}
-static int wdc_get_ocp_c1_log_page(nvme_root_t r, int fd, char *format)
+static int wdc_get_ocp_c1_log_page(nvme_root_t r, struct nvme_dev *dev, char *format)
{
int ret = 0;
int fmt = -1;
@@ -6787,7 +6879,7 @@ static int wdc_get_ocp_c1_log_page(nvme_root_t r, int fd, char *format)
int i;
struct wdc_ocp_c1_error_recovery_log *log_data;
- if (!wdc_check_device(r, fd))
+ if (!wdc_check_device(r, dev))
return -1;
fmt = validate_output_format(format);
if (fmt < 0) {
@@ -6801,8 +6893,8 @@ static int wdc_get_ocp_c1_log_page(nvme_root_t r, int fd, char *format)
}
memset(data, 0, sizeof (__u8) * WDC_ERROR_REC_LOG_BUF_LEN);
- ret = nvme_get_log_simple(fd, WDC_ERROR_REC_LOG_ID,
- WDC_ERROR_REC_LOG_BUF_LEN, data);
+ ret = nvme_get_log_simple(dev_fd(dev), WDC_ERROR_REC_LOG_ID,
+ WDC_ERROR_REC_LOG_BUF_LEN, data);
if (strcmp(format, "json"))
fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret, false), ret);
@@ -6811,7 +6903,8 @@ static int wdc_get_ocp_c1_log_page(nvme_root_t r, int fd, char *format)
log_data = (struct wdc_ocp_c1_error_recovery_log *)data;
/* check log page version */
- if (log_data->log_page_version != WDC_ERROR_REC_LOG_VERSION) {
+ if ((log_data->log_page_version != WDC_ERROR_REC_LOG_VERSION1) &&
+ (log_data->log_page_version != WDC_ERROR_REC_LOG_VERSION2)) {
fprintf(stderr, "ERROR : WDC : invalid error recovery log version - %d\n", log_data->log_page_version);
ret = -1;
goto out;
@@ -6848,7 +6941,7 @@ out:
return ret;
}
-static int wdc_get_ocp_c4_log_page(nvme_root_t r, int fd, char *format)
+static int wdc_get_ocp_c4_log_page(nvme_root_t r, struct nvme_dev *dev, char *format)
{
int ret = 0;
int fmt = -1;
@@ -6856,7 +6949,7 @@ static int wdc_get_ocp_c4_log_page(nvme_root_t r, int fd, char *format)
int i;
struct wdc_ocp_C4_dev_cap_log *log_data;
- if (!wdc_check_device(r, fd))
+ if (!wdc_check_device(r, dev))
return -1;
fmt = validate_output_format(format);
if (fmt < 0) {
@@ -6870,8 +6963,8 @@ static int wdc_get_ocp_c4_log_page(nvme_root_t r, int fd, char *format)
}
memset(data, 0, sizeof (__u8) * WDC_DEV_CAP_LOG_BUF_LEN);
- ret = nvme_get_log_simple(fd, WDC_DEV_CAP_LOG_ID,
- WDC_DEV_CAP_LOG_BUF_LEN, data);
+ ret = nvme_get_log_simple(dev_fd(dev), WDC_DEV_CAP_LOG_ID,
+ WDC_DEV_CAP_LOG_BUF_LEN, data);
if (strcmp(format, "json"))
fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret, false), ret);
@@ -6893,7 +6986,7 @@ static int wdc_get_ocp_c4_log_page(nvme_root_t r, int fd, char *format)
int j;
fprintf(stderr, "ERROR : WDC : Expected GUID: 0x");
for (j = 0; j<16; j++) {
- fprintf(stderr, "%x", wdc_ocp_c1_guid[j]);
+ fprintf(stderr, "%x", wdc_ocp_c4_guid[j]);
}
fprintf(stderr, "\nERROR : WDC : Actual GUID: 0x");
for (j = 0; j<16; j++) {
@@ -6917,7 +7010,7 @@ out:
return ret;
}
-static int wdc_get_ocp_c5_log_page(nvme_root_t r, int fd, char *format)
+static int wdc_get_ocp_c5_log_page(nvme_root_t r, struct nvme_dev *dev, char *format)
{
int ret = 0;
int fmt = -1;
@@ -6925,7 +7018,7 @@ static int wdc_get_ocp_c5_log_page(nvme_root_t r, int fd, char *format)
int i;
struct wdc_ocp_C5_unsupported_reqs *log_data;
- if (!wdc_check_device(r, fd))
+ if (!wdc_check_device(r, dev))
return -1;
fmt = validate_output_format(format);
if (fmt < 0) {
@@ -6939,8 +7032,8 @@ static int wdc_get_ocp_c5_log_page(nvme_root_t r, int fd, char *format)
}
memset(data, 0, sizeof (__u8) * WDC_UNSUPPORTED_REQS_LOG_BUF_LEN);
- ret = nvme_get_log_simple(fd, WDC_UNSUPPORTED_REQS_LOG_ID,
- WDC_UNSUPPORTED_REQS_LOG_BUF_LEN, data);
+ ret = nvme_get_log_simple(dev_fd(dev), WDC_UNSUPPORTED_REQS_LOG_ID,
+ WDC_UNSUPPORTED_REQS_LOG_BUF_LEN, data);
if (strcmp(format, "json"))
fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret, false), ret);
@@ -6962,7 +7055,7 @@ static int wdc_get_ocp_c5_log_page(nvme_root_t r, int fd, char *format)
int j;
fprintf(stderr, "ERROR : WDC : Expected GUID: 0x");
for (j = 0; j<16; j++) {
- fprintf(stderr, "%x", wdc_ocp_c1_guid[j]);
+ fprintf(stderr, "%x", wdc_ocp_c5_guid[j]);
}
fprintf(stderr, "\nERROR : WDC : Actual GUID: 0x");
for (j = 0; j<16; j++) {
@@ -6986,14 +7079,14 @@ out:
return ret;
}
-static int wdc_get_d0_log_page(nvme_root_t r, int fd, char *format)
+static int wdc_get_d0_log_page(nvme_root_t r, struct nvme_dev *dev, char *format)
{
int ret = 0;
int fmt = -1;
__u8 *data;
struct wdc_ssd_d0_smart_log *perf;
- if (!wdc_check_device(r, fd))
+ if (!wdc_check_device(r, dev))
return -1;
fmt = validate_output_format(format);
if (fmt < 0) {
@@ -7002,7 +7095,7 @@ static int wdc_get_d0_log_page(nvme_root_t r, int fd, char *format)
}
/* verify the 0xD0 log page is supported */
- if (wdc_nvme_check_supported_log_page(r, fd, WDC_NVME_GET_VU_SMART_LOG_OPCODE) == false) {
+ if (wdc_nvme_check_supported_log_page(r, dev, WDC_NVME_GET_VU_SMART_LOG_OPCODE) == false) {
fprintf(stderr, "ERROR : WDC : 0xD0 Log Page not supported\n");
return -1;
}
@@ -7013,8 +7106,9 @@ static int wdc_get_d0_log_page(nvme_root_t r, int fd, char *format)
}
memset(data, 0, sizeof (__u8) * WDC_NVME_VU_SMART_LOG_LEN);
- ret = nvme_get_log_simple(fd, WDC_NVME_GET_VU_SMART_LOG_OPCODE,
- WDC_NVME_VU_SMART_LOG_LEN, data);
+ ret = nvme_get_log_simple(dev_fd(dev),
+ WDC_NVME_GET_VU_SMART_LOG_OPCODE,
+ WDC_NVME_VU_SMART_LOG_LEN, data);
if (strcmp(format, "json"))
nvme_show_status(ret);
@@ -7036,10 +7130,10 @@ static int wdc_vs_smart_add_log(int argc, char **argv, struct command *command,
{
const char *desc = "Retrieve additional performance statistics.";
const char *interval = "Interval to read the statistics from [1, 15].";
- int fd;
const char *log_page_version = "Log Page Version: 0 = vendor, 1 = WDC";
const char *log_page_mask = "Log Page Mask, comma separated list: 0xC0, 0xC1, 0xCA, 0xD0";
const char *namespace_id = "desired namespace id";
+ struct nvme_dev *dev;
nvme_root_t r;
int ret = 0;
int uuid_index = 0;
@@ -7072,9 +7166,9 @@ static int wdc_vs_smart_add_log(int argc, char **argv, struct command *command,
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
+ if (ret)
+ return ret;
r = nvme_scan(NULL);
if (cfg.log_page_version == 0) {
@@ -7121,7 +7215,7 @@ static int wdc_vs_smart_add_log(int argc, char **argv, struct command *command,
fprintf(stderr, "ERROR : WDC: Unknown log page mask - %s\n", cfg.log_page_mask);
- capabilities = wdc_get_drive_capabilities(r, fd);
+ capabilities = wdc_get_drive_capabilities(r, dev);
if ((capabilities & WDC_DRIVE_CAP_SMART_LOG_MASK) == 0) {
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
@@ -7132,35 +7226,37 @@ static int wdc_vs_smart_add_log(int argc, char **argv, struct command *command,
if (((capabilities & WDC_DRIVE_CAP_C0_LOG_PAGE) == WDC_DRIVE_CAP_C0_LOG_PAGE) &&
(page_mask & WDC_C0_PAGE_MASK)) {
/* Get 0xC0 log page if possible. */
- ret = wdc_get_c0_log_page(r, fd, cfg.output_format, uuid_index, cfg.namespace_id);
+ ret = wdc_get_c0_log_page(r, dev, cfg.output_format,
+ uuid_index, cfg.namespace_id);
if (ret)
fprintf(stderr, "ERROR : WDC : Failure reading the C0 Log Page, ret = %d\n", ret);
}
if (((capabilities & (WDC_DRIVE_CAP_CA_LOG_PAGE)) == (WDC_DRIVE_CAP_CA_LOG_PAGE)) &&
(page_mask & WDC_CA_PAGE_MASK)) {
/* Get the CA Log Page */
- ret = wdc_get_ca_log_page(r, fd, cfg.output_format);
+ ret = wdc_get_ca_log_page(r, dev, 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, fd, cfg.output_format, cfg.interval);
+ ret = wdc_get_c1_log_page(r, dev, cfg.output_format,
+ cfg.interval);
if (ret)
fprintf(stderr, "ERROR : WDC : Failure reading the C1 Log Page, ret = %d\n", ret);
}
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, fd, cfg.output_format);
+ ret = wdc_get_d0_log_page(r, dev, cfg.output_format);
if (ret)
fprintf(stderr, "ERROR : WDC : Failure reading the D0 Log Page, ret = %d\n", ret);
}
out:
nvme_free_tree(r);
- close(fd);
+ dev_close(dev);
return ret;
}
@@ -7169,12 +7265,11 @@ static int wdc_vs_cloud_log(int argc, char **argv, struct command *command,
{
const char *desc = "Retrieve Cloud Log Smart/Health Information";
const char *namespace_id = "desired namespace id";
- int fd;
- nvme_root_t r;
- int ret = 0;
__u64 capabilities = 0;
+ struct nvme_dev *dev;
+ int ret, fmt = -1;
+ nvme_root_t r;
__u8 *data;
- int fmt = -1;
struct config {
char *output_format;
@@ -7192,13 +7287,13 @@ static int wdc_vs_cloud_log(int argc, char **argv, struct command *command,
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
+ if (ret)
+ return ret;
r = nvme_scan(NULL);
- capabilities = wdc_get_drive_capabilities(r, fd);
+ capabilities = wdc_get_drive_capabilities(r, dev);
if ((capabilities & WDC_DRIVE_CAP_CLOUD_LOG_PAGE) == 0) {
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
@@ -7207,7 +7302,8 @@ static int wdc_vs_cloud_log(int argc, char **argv, struct command *command,
}
data = NULL;
- ret = nvme_get_ext_smart_cloud_log(fd, &data, 0, cfg.namespace_id);
+ ret = nvme_get_ext_smart_cloud_log(dev_fd(dev), &data, 0,
+ cfg.namespace_id);
if (strcmp(cfg.output_format, "json"))
nvme_show_status(ret);
@@ -7231,7 +7327,7 @@ static int wdc_vs_cloud_log(int argc, char **argv, struct command *command,
out:
nvme_free_tree(r);
- close(fd);
+ dev_close(dev);
return ret;
}
@@ -7240,12 +7336,11 @@ static int wdc_vs_hw_rev_log(int argc, char **argv, struct command *command,
{
const char *desc = "Retrieve Hardware Revision Log Information";
const char *namespace_id = "desired namespace id";
- int fd;
- nvme_root_t r;
- int ret = 0;
__u64 capabilities = 0;
+ struct nvme_dev *dev;
+ int ret, fmt = -1;
__u8 *data = NULL;
- int fmt = -1;
+ nvme_root_t r;
struct config {
char *output_format;
@@ -7263,13 +7358,13 @@ static int wdc_vs_hw_rev_log(int argc, char **argv, struct command *command,
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
+ if (ret)
+ return ret;
r = nvme_scan(NULL);
- capabilities = wdc_get_drive_capabilities(r, fd);
+ capabilities = wdc_get_drive_capabilities(r, dev);
if ((capabilities & WDC_DRIVE_CAP_HW_REV_LOG_PAGE) == 0) {
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
@@ -7277,7 +7372,7 @@ static int wdc_vs_hw_rev_log(int argc, char **argv, struct command *command,
goto out;
}
- ret = nvme_get_hw_rev_log(fd, &data, 0, cfg.namespace_id);
+ ret = nvme_get_hw_rev_log(dev_fd(dev), &data, 0, cfg.namespace_id);
if (strcmp(cfg.output_format, "json"))
nvme_show_status(ret);
@@ -7314,7 +7409,7 @@ free_buf:
out:
nvme_free_tree(r);
- close(fd);
+ dev_close(dev);
return ret;
}
@@ -7324,8 +7419,8 @@ static int wdc_vs_device_waf(int argc, char **argv, struct command *command,
const char *desc = "Retrieve Device Write Amplication Factor";
const char *namespace_id = "desired namespace id";
struct nvme_smart_log smart_log;
+ struct nvme_dev *dev;
__u8 *data;
- int fd;
nvme_root_t r;
int ret = 0;
int fmt = -1;
@@ -7354,13 +7449,13 @@ static int wdc_vs_device_waf(int argc, char **argv, struct command *command,
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
+ if (ret)
+ return ret;
r = nvme_scan(NULL);
- capabilities = wdc_get_drive_capabilities(r, fd);
+ capabilities = wdc_get_drive_capabilities(r, dev);
if ((capabilities & WDC_DRIVE_CAP_DEVICE_WAF) == 0) {
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
@@ -7369,7 +7464,8 @@ 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(fd, cfg.namespace_id, false, &smart_log);
+ ret = nvme_get_log_smart(dev_fd(dev), cfg.namespace_id, false,
+ &smart_log);
if (!ret) {
data_units_written = int128_to_double(smart_log.data_units_written);
}
@@ -7385,7 +7481,8 @@ 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(fd, &data, 0, cfg.namespace_id);
+ ret = nvme_get_ext_smart_cloud_log(dev_fd(dev), &data, 0,
+ cfg.namespace_id);
if (ret == 0) {
ext_smart_log_ptr = (wdc_nvme_ext_smart_log *)data;
@@ -7438,7 +7535,7 @@ static int wdc_vs_device_waf(int argc, char **argv, struct command *command,
out:
nvme_free_tree(r);
- close(fd);
+ dev_close(dev);
return ret;
}
@@ -7446,10 +7543,10 @@ static int wdc_get_latency_monitor_log(int argc, char **argv, struct command *co
struct plugin *plugin)
{
const char *desc = "Retrieve latency monitor log data.";
+ __u64 capabilities = 0;
+ struct nvme_dev *dev;
nvme_root_t r;
- int fd;
int ret = 0;
- __u64 capabilities = 0;
struct config {
char *output_format;
@@ -7464,12 +7561,12 @@ static int wdc_get_latency_monitor_log(int argc, char **argv, struct command *co
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
+ if (ret)
+ return ret;
r = nvme_scan(NULL);
- capabilities = wdc_get_drive_capabilities(r, fd);
+ capabilities = wdc_get_drive_capabilities(r, dev);
if ((capabilities & WDC_DRIVE_CAP_C3_LOG_PAGE) == 0) {
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
@@ -7477,13 +7574,13 @@ static int wdc_get_latency_monitor_log(int argc, char **argv, struct command *co
goto out;
}
- ret = wdc_get_c3_log_page(r, fd, cfg.output_format);
+ ret = wdc_get_c3_log_page(r, dev, 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);
- close(fd);
+ dev_close(dev);
return ret;
}
@@ -7491,10 +7588,10 @@ static int wdc_get_error_recovery_log(int argc, char **argv, struct command *com
struct plugin *plugin)
{
const char *desc = "Retrieve error recovery log data.";
+ __u64 capabilities = 0;
+ struct nvme_dev *dev;
nvme_root_t r;
- int fd;
int ret = 0;
- __u64 capabilities = 0;
struct config {
char *output_format;
@@ -7509,12 +7606,12 @@ static int wdc_get_error_recovery_log(int argc, char **argv, struct command *com
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
+ if (ret)
+ return ret;
r = nvme_scan(NULL);
- capabilities = wdc_get_drive_capabilities(r, fd);
+ capabilities = wdc_get_drive_capabilities(r, dev);
if ((capabilities & WDC_DRIVE_CAP_OCP_C1_LOG_PAGE) == 0) {
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
@@ -7522,13 +7619,13 @@ static int wdc_get_error_recovery_log(int argc, char **argv, struct command *com
goto out;
}
- ret = wdc_get_ocp_c1_log_page(r, fd, cfg.output_format);
+ ret = wdc_get_ocp_c1_log_page(r, dev, 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);
- close(fd);
+ dev_close(dev);
return ret;
}
@@ -7536,10 +7633,10 @@ static int wdc_get_dev_capabilities_log(int argc, char **argv, struct command *c
struct plugin *plugin)
{
const char *desc = "Retrieve device capabilities log data.";
+ __u64 capabilities = 0;
+ struct nvme_dev *dev;
nvme_root_t r;
- int fd;
int ret = 0;
- __u64 capabilities = 0;
struct config {
char *output_format;
@@ -7554,12 +7651,12 @@ static int wdc_get_dev_capabilities_log(int argc, char **argv, struct command *c
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
+ if (ret)
+ return ret;
r = nvme_scan(NULL);
- capabilities = wdc_get_drive_capabilities(r, fd);
+ capabilities = wdc_get_drive_capabilities(r, dev);
if ((capabilities & WDC_DRIVE_CAP_OCP_C4_LOG_PAGE) == 0) {
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
@@ -7567,13 +7664,13 @@ static int wdc_get_dev_capabilities_log(int argc, char **argv, struct command *c
goto out;
}
- ret = wdc_get_ocp_c4_log_page(r, fd, cfg.output_format);
+ ret = wdc_get_ocp_c4_log_page(r, dev, 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);
- close(fd);
+ dev_close(dev);
return ret;
}
@@ -7581,10 +7678,10 @@ static int wdc_get_unsupported_reqs_log(int argc, char **argv, struct command *c
struct plugin *plugin)
{
const char *desc = "Retrieve unsupported requirements log data.";
+ __u64 capabilities = 0;
+ struct nvme_dev *dev;
nvme_root_t r;
- int fd;
int ret = 0;
- __u64 capabilities = 0;
struct config {
char *output_format;
@@ -7599,12 +7696,12 @@ static int wdc_get_unsupported_reqs_log(int argc, char **argv, struct command *c
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
+ if (ret)
+ return ret;
r = nvme_scan(NULL);
- capabilities = wdc_get_drive_capabilities(r, fd);
+ capabilities = wdc_get_drive_capabilities(r, dev);
if ((capabilities & WDC_DRIVE_CAP_OCP_C5_LOG_PAGE) == 0) {
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
@@ -7612,13 +7709,13 @@ static int wdc_get_unsupported_reqs_log(int argc, char **argv, struct command *c
goto out;
}
- ret = wdc_get_ocp_c5_log_page(r, fd, cfg.output_format);
+ ret = wdc_get_ocp_c5_log_page(r, dev, 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);
- close(fd);
+ dev_close(dev);
return ret;
}
@@ -7667,25 +7764,26 @@ static int wdc_clear_pcie_correctable_errors(int argc, char **argv, struct comma
struct plugin *plugin)
{
char *desc = "Clear PCIE Correctable Errors.";
- int fd, ret;
- nvme_root_t r;
__u64 capabilities = 0;
+ struct nvme_dev *dev;
+ nvme_root_t r;
+ int ret;
OPT_ARGS(opts) = {
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
+ if (ret)
+ return ret;
r = nvme_scan(NULL);
- if (!wdc_check_device(r, fd)) {
+ if (!wdc_check_device(r, dev)) {
ret = -1;
goto out;
}
- capabilities = wdc_get_drive_capabilities(r, fd);
+ capabilities = wdc_get_drive_capabilities(r, dev);
if ((capabilities & WDC_DRIVE_CAP_CLEAR_PCIE_MASK) == 0) {
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
ret = -1;
@@ -7693,18 +7791,18 @@ 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(fd);
+ ret = wdc_do_clear_pcie_correctable_errors(dev_fd(dev));
}
else if (capabilities & WDC_DRIVE_CAP_VUC_CLEAR_PCIE) {
- ret = wdc_do_clear_pcie_correctable_errors_vuc(fd);
+ ret = wdc_do_clear_pcie_correctable_errors_vuc(dev_fd(dev));
}
else {
- ret = wdc_do_clear_pcie_correctable_errors_fid(fd);
+ ret = wdc_do_clear_pcie_correctable_errors_fid(dev_fd(dev));
}
out:
nvme_free_tree(r);
- close(fd);
+ dev_close(dev);
return ret;
}
@@ -7712,7 +7810,7 @@ static int wdc_drive_status(int argc, char **argv, struct command *command,
struct plugin *plugin)
{
char *desc = "Get Drive Status.";
- int fd;
+ struct nvme_dev *dev;
int ret = 0;
nvme_root_t r;
__le32 system_eol_state;
@@ -7727,12 +7825,12 @@ static int wdc_drive_status(int argc, char **argv, struct command *command,
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
+ if (ret)
+ return ret;
r = nvme_scan(NULL);
- capabilities = wdc_get_drive_capabilities(r, fd);
+ capabilities = wdc_get_drive_capabilities(r, dev);
if ((capabilities & WDC_DRIVE_CAP_DRIVE_STATUS) != WDC_DRIVE_CAP_DRIVE_STATUS) {
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
ret = -1;
@@ -7740,41 +7838,42 @@ static int wdc_drive_status(int argc, char **argv, struct command *command,
}
/* verify the 0xC2 Device Manageability log page is supported */
- if (wdc_nvme_check_supported_log_page(r, fd, WDC_NVME_GET_DEV_MGMNT_LOG_PAGE_OPCODE) == false) {
+ if (wdc_nvme_check_supported_log_page(r, dev,
+ WDC_NVME_GET_DEV_MGMNT_LOG_PAGE_OPCODE) == false) {
fprintf(stderr, "ERROR : WDC : 0xC2 Log Page not supported\n");
ret = -1;
goto out;
}
/* Get the assert dump present status */
- if (!wdc_nvme_get_dev_status_log_data(r, fd, &assert_status,
+ if (!wdc_nvme_get_dev_status_log_data(r, dev, &assert_status,
WDC_C2_ASSERT_DUMP_PRESENT_ID))
fprintf(stderr, "ERROR : WDC : Get Assert Status Failed\n");
/* Get the thermal throttling status */
- if (!wdc_nvme_get_dev_status_log_data(r, fd, &thermal_status,
+ if (!wdc_nvme_get_dev_status_log_data(r, dev, &thermal_status,
WDC_C2_THERMAL_THROTTLE_STATUS_ID))
fprintf(stderr, "ERROR : WDC : Get Thermal Throttling Status Failed\n");
/* Get EOL status */
- if (!wdc_nvme_get_dev_status_log_data(r, fd, &eol_status,
+ if (!wdc_nvme_get_dev_status_log_data(r, dev, &eol_status,
WDC_C2_USER_EOL_STATUS_ID)) {
fprintf(stderr, "ERROR : WDC : Get User EOL Status Failed\n");
eol_status = cpu_to_le32(-1);
}
/* Get Customer EOL state */
- if (!wdc_nvme_get_dev_status_log_data(r, fd, &user_eol_state,
+ if (!wdc_nvme_get_dev_status_log_data(r, dev, &user_eol_state,
WDC_C2_USER_EOL_STATE_ID))
fprintf(stderr, "ERROR : WDC : Get User EOL State Failed\n");
/* Get System EOL state*/
- if (!wdc_nvme_get_dev_status_log_data(r, fd, &system_eol_state,
+ if (!wdc_nvme_get_dev_status_log_data(r, dev, &system_eol_state,
WDC_C2_SYSTEM_EOL_STATE_ID))
fprintf(stderr, "ERROR : WDC : Get System EOL State Failed\n");
/* Get format corrupt reason*/
- if (!wdc_nvme_get_dev_status_log_data(r, fd, &format_corrupt_reason,
+ if (!wdc_nvme_get_dev_status_log_data(r, dev, &format_corrupt_reason,
WDC_C2_FORMAT_CORRUPT_REASON_ID))
fprintf(stderr, "ERROR : WDC : Get Format Corrupt Reason Failed\n");
@@ -7822,7 +7921,7 @@ static int wdc_drive_status(int argc, char **argv, struct command *command,
out:
nvme_free_tree(r);
- close(fd);
+ dev_close(dev);
return ret;
}
@@ -7830,7 +7929,7 @@ static int wdc_clear_assert_dump(int argc, char **argv, struct command *command,
struct plugin *plugin)
{
char *desc = "Clear Assert Dump Present Status.";
- int fd;
+ struct nvme_dev *dev;
int ret = -1;
nvme_root_t r;
__le32 assert_status = cpu_to_le32(0xFFFFFFFF);
@@ -7841,18 +7940,18 @@ static int wdc_clear_assert_dump(int argc, char **argv, struct command *command,
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
+ if (ret)
+ return ret;
r = nvme_scan(NULL);
- capabilities = wdc_get_drive_capabilities(r, fd);
+ capabilities = wdc_get_drive_capabilities(r, dev);
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, fd, &assert_status,
+ if (!wdc_nvme_get_dev_status_log_data(r, dev, &assert_status,
WDC_C2_ASSERT_DUMP_PRESENT_ID)) {
fprintf(stderr, "ERROR : WDC : Get Assert Status Failed\n");
ret = -1;
@@ -7866,25 +7965,27 @@ 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(fd, &admin_cmd, NULL);
+ ret = nvme_submit_admin_passthru(dev_fd(dev), &admin_cmd,
+ NULL);
nvme_show_status(ret);
} else
fprintf(stderr, "INFO : WDC : No Assert Dump Present\n");
out:
nvme_free_tree(r);
- close(fd);
+ dev_close(dev);
return ret;
}
-static int wdc_get_fw_act_history(nvme_root_t r, int fd, char *format)
+static int wdc_get_fw_act_history(nvme_root_t r, struct nvme_dev *dev,
+ char *format)
{
int ret = 0;
int fmt = -1;
__u8 *data;
struct wdc_fw_act_history_log_hdr *fw_act_history_hdr;
- if (!wdc_check_device(r, fd))
+ if (!wdc_check_device(r, dev))
return -1;
fmt = validate_output_format(format);
@@ -7894,7 +7995,7 @@ static int wdc_get_fw_act_history(nvme_root_t r, int fd, char *format)
}
/* verify the FW Activate History log page is supported */
- if (wdc_nvme_check_supported_log_page(r, fd, WDC_NVME_GET_FW_ACT_HISTORY_LOG_ID) == false) {
+ if (wdc_nvme_check_supported_log_page(r, dev, WDC_NVME_GET_FW_ACT_HISTORY_LOG_ID) == false) {
fprintf(stderr, "ERROR : WDC : %d Log Page not supported\n", WDC_NVME_GET_FW_ACT_HISTORY_LOG_ID);
return -1;
}
@@ -7906,8 +8007,9 @@ static int wdc_get_fw_act_history(nvme_root_t r, int fd, char *format)
memset(data, 0, sizeof (__u8) * WDC_FW_ACT_HISTORY_LOG_BUF_LEN);
- ret = nvme_get_log_simple(fd, WDC_NVME_GET_FW_ACT_HISTORY_LOG_ID,
- WDC_FW_ACT_HISTORY_LOG_BUF_LEN, data);
+ ret = nvme_get_log_simple(dev_fd(dev),
+ WDC_NVME_GET_FW_ACT_HISTORY_LOG_ID,
+ WDC_FW_ACT_HISTORY_LOG_BUF_LEN, data);
if (strcmp(format, "json"))
nvme_show_status(ret);
@@ -7935,13 +8037,13 @@ static int wdc_get_fw_act_history(nvme_root_t r, int fd, char *format)
return ret;
}
-static __u32 wdc_get_fw_cust_id(nvme_root_t r, int fd)
+static __u32 wdc_get_fw_cust_id(nvme_root_t r, struct nvme_dev *dev)
{
__u32 cust_id = WDC_INVALID_CUSTOMER_ID;
__u32 *cust_id_ptr = NULL;
- if (!(get_dev_mgment_cbs_data(r, fd, WDC_C2_CUSTOMER_ID_ID, (void*)&cust_id_ptr))) {
+ if (!(get_dev_mgment_cbs_data(r, dev, 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 {
cust_id = *cust_id_ptr;
@@ -7951,7 +8053,8 @@ static __u32 wdc_get_fw_cust_id(nvme_root_t r, int fd)
return cust_id;
}
-static int wdc_get_fw_act_history_C2(nvme_root_t r, int fd, char *format)
+static int wdc_get_fw_act_history_C2(nvme_root_t r, struct nvme_dev *dev,
+ char *format)
{
int ret = 0;
int fmt = -1;
@@ -7961,7 +8064,7 @@ static int wdc_get_fw_act_history_C2(nvme_root_t r, int fd, char *format)
__u32 tot_entries = 0, num_entries = 0;
__u32 vendor_id = 0, device_id = 0;
- if (!wdc_check_device(r, fd))
+ if (!wdc_check_device(r, dev))
return -1;
fmt = validate_output_format(format);
@@ -7970,7 +8073,7 @@ static int wdc_get_fw_act_history_C2(nvme_root_t r, int fd, char *format)
return fmt;
}
- ret = wdc_get_pci_ids(r, &device_id, &vendor_id);
+ ret = wdc_get_pci_ids(r, dev, &device_id, &vendor_id);
if ((data = (__u8*) malloc(sizeof (__u8) * WDC_FW_ACT_HISTORY_C2_LOG_BUF_LEN)) == NULL) {
fprintf(stderr, "ERROR : WDC : malloc : %s\n", strerror(errno));
@@ -7979,8 +8082,9 @@ static int wdc_get_fw_act_history_C2(nvme_root_t r, int fd, char *format)
memset(data, 0, sizeof (__u8) * WDC_FW_ACT_HISTORY_C2_LOG_BUF_LEN);
- ret = nvme_get_log_simple(fd, WDC_NVME_GET_FW_ACT_HISTORY_C2_LOG_ID,
- WDC_FW_ACT_HISTORY_C2_LOG_BUF_LEN, data);
+ ret = nvme_get_log_simple(dev_fd(dev),
+ WDC_NVME_GET_FW_ACT_HISTORY_C2_LOG_ID,
+ WDC_FW_ACT_HISTORY_C2_LOG_BUF_LEN, data);
if (strcmp(format, "json"))
nvme_show_status(ret);
@@ -7992,7 +8096,7 @@ static int wdc_get_fw_act_history_C2(nvme_root_t r, int fd, char *format)
if (tot_entries > 0) {
/* get the FW customer id */
- cust_id = wdc_get_fw_cust_id(r, fd);
+ cust_id = wdc_get_fw_cust_id(r, dev);
if (cust_id == WDC_INVALID_CUSTOMER_ID) {
fprintf(stderr, "%s: ERROR : WDC : invalid customer id\n", __func__);
ret = -1;
@@ -8018,12 +8122,11 @@ freeData:
static int wdc_vs_fw_activate_history(int argc, char **argv, struct command *command,
struct plugin *plugin)
{
- int fd;
- int ret = 0;
- nvme_root_t r;
- __u64 capabilities = 0;
const char *desc = "Retrieve FW activate history table.";
-
+ __u64 capabilities = 0;
+ struct nvme_dev *dev;
+ nvme_root_t r;
+ int ret;
struct config {
char *output_format;
@@ -8038,13 +8141,12 @@ static int wdc_vs_fw_activate_history(int argc, char **argv, struct command *com
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
-
- if (fd < 0)
- return fd;
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
+ if (ret)
+ return ret;
r = nvme_scan(NULL);
- capabilities = wdc_get_drive_capabilities(r, fd);
+ capabilities = wdc_get_drive_capabilities(r, dev);
if ((capabilities & WDC_DRIVE_CAP_FW_ACTIVATE_HISTORY_MASK) == 0) {
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
ret = -1;
@@ -8068,8 +8170,8 @@ static int wdc_vs_fw_activate_history(int argc, char **argv, struct command *com
/* 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_OPCODE,
+ .fd = dev_fd(dev),
+ .lid = WDC_NVME_GET_SMART_CLOUD_ATTR_LOG_ID,
.nsid = 0xFFFFFFFF,
.lpo = 0,
.lsp = NVME_LOG_LSP_NONE,
@@ -8101,21 +8203,22 @@ static int wdc_vs_fw_activate_history(int argc, char **argv, struct command *com
free(data);
if (c0GuidMatch) {
- ret = wdc_get_fw_act_history_C2(r, fd,
+ ret = wdc_get_fw_act_history_C2(r, dev,
cfg.output_format);
}
else {
- ret = wdc_get_fw_act_history(r, fd, cfg.output_format);
+ ret = wdc_get_fw_act_history(r, dev,
+ cfg.output_format);
}
} else {
- ret = wdc_get_fw_act_history_C2(r, fd, cfg.output_format);
+ ret = wdc_get_fw_act_history_C2(r, dev, cfg.output_format);
}
if (ret)
fprintf(stderr, "ERROR : WDC : Failure reading the FW Activate History, ret = %d\n", ret);
out:
nvme_free_tree(r);
- close(fd);
+ dev_close(dev);
return ret;
}
@@ -8152,21 +8255,21 @@ static int wdc_clear_fw_activate_history(int argc, char **argv, struct command *
struct plugin *plugin)
{
char *desc = "Clear FW activate history table.";
- int fd;
- int ret = -1;
- nvme_root_t r;
__u64 capabilities = 0;
+ struct nvme_dev *dev;
+ nvme_root_t r;
+ int ret;
OPT_ARGS(opts) = {
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
+ if (ret)
+ return ret;
r = nvme_scan(NULL);
- capabilities = wdc_get_drive_capabilities(r, fd);
+ capabilities = wdc_get_drive_capabilities(r, dev);
if ((capabilities & WDC_DRIVE_CAP_CLEAR_FW_ACT_HISTORY_MASK) == 0) {
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
ret = -1;
@@ -8174,13 +8277,13 @@ 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(fd);
+ ret = wdc_do_clear_fw_activate_history_vuc(dev_fd(dev));
else
- ret = wdc_do_clear_fw_activate_history_fid(fd);
+ ret = wdc_do_clear_fw_activate_history_fid(dev_fd(dev));
out:
nvme_free_tree(r);
- close(fd);
+ dev_close(dev);
return ret;
}
@@ -8191,11 +8294,11 @@ static int wdc_vs_telemetry_controller_option(int argc, char **argv, struct comm
char *disable = "Disable controller option of the telemetry log page.";
char *enable = "Enable controller option of the telemetry log page.";
char *status = "Displays the current state of the controller initiated log page.";
- int fd;
- int ret = -1;
- nvme_root_t r;
__u64 capabilities = 0;
+ struct nvme_dev *dev;
+ nvme_root_t r;
__u32 result;
+ int ret = -1;
struct config {
@@ -8217,12 +8320,12 @@ static int wdc_vs_telemetry_controller_option(int argc, char **argv, struct comm
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
+ if (ret)
+ return ret;
r = nvme_scan(NULL);
- capabilities = wdc_get_drive_capabilities(r, fd);
+ capabilities = wdc_get_drive_capabilities(r, dev);
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;
@@ -8238,19 +8341,22 @@ static int wdc_vs_telemetry_controller_option(int argc, char **argv, struct comm
}
if (cfg.disable) {
- ret = nvme_set_features_simple(fd, WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID, 0, 1,
- false, &result);
+ ret = nvme_set_features_simple(dev_fd(dev),
+ WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID,
+ 0, 1, false, &result);
- wdc_clear_reason_id(fd);
+ wdc_clear_reason_id(dev);
}
else {
if (cfg.enable) {
- ret = nvme_set_features_simple(fd, WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID, 0, 0,
- false, &result);
+ ret = nvme_set_features_simple(dev_fd(dev),
+ WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID,
+ 0, 0, false, &result);
}
else if (cfg.status) {
- ret = nvme_get_features_simple(fd, WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID, 0,
- &result);
+ ret = nvme_get_features_simple(dev_fd(dev),
+ WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID,
+ 0, &result);
if (ret == 0) {
if (result)
fprintf(stderr, "Controller Option Telemetry Log Page State: Disabled\n");
@@ -8271,12 +8377,12 @@ static int wdc_vs_telemetry_controller_option(int argc, char **argv, struct comm
out:
nvme_free_tree(r);
- close(fd);
+ dev_close(dev);
return ret;
}
-static int wdc_get_serial_and_fw_rev(int fd, char *sn, char *fw_rev)
+static int wdc_get_serial_and_fw_rev(struct nvme_dev *dev, char *sn, char *fw_rev)
{
int i;
int ret;
@@ -8286,7 +8392,7 @@ static int wdc_get_serial_and_fw_rev(int fd, char *sn, char *fw_rev)
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(fd, &ctrl);
+ ret = nvme_identify_ctrl(dev_fd(dev), &ctrl);
if (ret) {
fprintf(stderr, "ERROR : WDC : nvme_identify_ctrl() failed "
"0x%x\n", ret);
@@ -8303,7 +8409,7 @@ static int wdc_get_serial_and_fw_rev(int fd, char *sn, char *fw_rev)
return 0;
}
-static int wdc_get_max_transfer_len(int fd, __u32 *maxTransferLen)
+static int wdc_get_max_transfer_len(struct nvme_dev *dev, __u32 *maxTransferLen)
{
int ret = 0;
struct nvme_id_ctrl ctrl;
@@ -8311,7 +8417,7 @@ static int wdc_get_max_transfer_len(int fd, __u32 *maxTransferLen)
__u32 maxTransferLenDevice = 0;
memset(&ctrl, 0, sizeof (struct nvme_id_ctrl));
- ret = nvme_identify_ctrl(fd, &ctrl);
+ ret = nvme_identify_ctrl(dev_fd(dev), &ctrl);
if (ret) {
fprintf(stderr, "ERROR : WDC : nvme_identify_ctrl() failed 0x%x\n", ret);
return -1;
@@ -8323,12 +8429,13 @@ static int wdc_get_max_transfer_len(int fd, __u32 *maxTransferLen)
return ret;
}
-static int wdc_de_VU_read_size(int fd, __u32 fileId, __u16 spiDestn, __u32* logSize)
+static int wdc_de_VU_read_size(struct nvme_dev *dev, __u32 fileId,
+ __u16 spiDestn, __u32* logSize)
{
int ret = WDC_STATUS_FAILURE;
struct nvme_passthru_cmd cmd;
- if(!fd || !logSize )
+ if(!dev || !logSize )
{
ret = WDC_STATUS_INVALID_PARAMETER;
goto end;
@@ -8340,7 +8447,7 @@ static int wdc_de_VU_read_size(int fd, __u32 fileId, __u16 spiDestn, __u32* logS
cmd.cdw13 = fileId<<16;
cmd.cdw14 = spiDestn;
- ret = nvme_submit_admin_passthru(fd, &cmd, NULL);
+ ret = nvme_submit_admin_passthru(dev_fd(dev), &cmd, NULL);
if (!ret && logSize)
*logSize = cmd.result;
@@ -8353,13 +8460,15 @@ static int wdc_de_VU_read_size(int fd, __u32 fileId, __u16 spiDestn, __u32* logS
return ret;
}
-static int wdc_de_VU_read_buffer(int fd, __u32 fileId, __u16 spiDestn, __u32 offsetInDwords, __u8* dataBuffer, __u32* bufferSize)
+static int wdc_de_VU_read_buffer(struct nvme_dev *dev, __u32 fileId,
+ __u16 spiDestn, __u32 offsetInDwords,
+ __u8* dataBuffer, __u32* bufferSize)
{
int ret = WDC_STATUS_FAILURE;
struct nvme_passthru_cmd cmd;
__u32 noOfDwordExpected = 0;
- if(!fd || !dataBuffer || !bufferSize)
+ if(!dev || !dataBuffer || !bufferSize)
{
ret = WDC_STATUS_INVALID_PARAMETER;
goto end;
@@ -8377,7 +8486,7 @@ static int wdc_de_VU_read_buffer(int fd, __u32 fileId, __u16 spiDestn, __u32 off
cmd.addr = (__u64)(__u64)(uintptr_t)dataBuffer;
cmd.data_len = *bufferSize;
- ret = nvme_submit_admin_passthru(fd, &cmd, NULL);
+ ret = nvme_submit_admin_passthru(dev_fd(dev), &cmd, NULL);
if( ret != WDC_STATUS_SUCCESS) {
fprintf(stderr, "ERROR : WDC : VUReadBuffer() failed, ");
@@ -8388,7 +8497,7 @@ static int wdc_de_VU_read_buffer(int fd, __u32 fileId, __u16 spiDestn, __u32 off
return ret;
}
-static int wdc_get_log_dir_max_entries(int fd, __u32* maxNumOfEntries)
+static int wdc_get_log_dir_max_entries(struct nvme_dev *dev, __u32* maxNumOfEntries)
{
int ret = WDC_STATUS_FAILURE;
__u32 headerPayloadSize = 0;
@@ -8398,13 +8507,13 @@ static int wdc_get_log_dir_max_entries(int fd, __u32* maxNumOfEntries)
__u16 fileOffset = 0;
- if (!fd || !maxNumOfEntries)
+ if (!dev || !maxNumOfEntries)
{
ret = WDC_STATUS_INVALID_PARAMETER;
return ret;
}
/* 1.Get log directory first four bytes */
- if (WDC_STATUS_SUCCESS != (ret = wdc_de_VU_read_size(fd, 0, 5, (__u32*)&headerPayloadSize)))
+ if (WDC_STATUS_SUCCESS != (ret = wdc_de_VU_read_size(dev, 0, 5, (__u32*)&headerPayloadSize)))
{
fprintf(stderr, "ERROR : WDC : %s: Failed to get headerPayloadSize from file directory 0x%x\n",
__func__, ret);
@@ -8415,7 +8524,7 @@ static int wdc_get_log_dir_max_entries(int fd, __u32* maxNumOfEntries)
fileIdOffsetsBuffer = (__u8*)calloc(1, fileIdOffsetsBufferSize);
/* 2.Read to get file offsets */
- if (WDC_STATUS_SUCCESS != (ret = wdc_de_VU_read_buffer(fd, 0, 5, 0, fileIdOffsetsBuffer, &fileIdOffsetsBufferSize)))
+ if (WDC_STATUS_SUCCESS != (ret = wdc_de_VU_read_buffer(dev, 0, 5, 0, fileIdOffsetsBuffer, &fileIdOffsetsBufferSize)))
{
fprintf(stderr, "ERROR : WDC : %s: Failed to get fileIdOffsets from file directory 0x%x\n",
__func__, ret);
@@ -8455,7 +8564,7 @@ static WDC_DRIVE_ESSENTIAL_TYPE wdc_get_essential_type(__u8 fileName[])
return essentialType;
}
-static int wdc_fetch_log_directory(int fd, PWDC_DE_VU_LOG_DIRECTORY directory)
+static int wdc_fetch_log_directory(struct nvme_dev *dev, PWDC_DE_VU_LOG_DIRECTORY directory)
{
int ret = WDC_STATUS_FAILURE;
__u8 *fileOffset = NULL;
@@ -8466,12 +8575,12 @@ static int wdc_fetch_log_directory(int fd, PWDC_DE_VU_LOG_DIRECTORY directory)
__u32 entryId = 0;
__u32 fileDirectorySize = 0;
- if (!fd || !directory) {
+ if (!dev || !directory) {
ret = WDC_STATUS_INVALID_PARAMETER;
goto end;
}
- ret = wdc_de_VU_read_size(fd, 0, 5, &fileDirectorySize);
+ ret = wdc_de_VU_read_size(dev, 0, 5, &fileDirectorySize);
if (WDC_STATUS_SUCCESS != ret) {
fprintf(stderr,
"ERROR : WDC : %s: Failed to get filesystem directory size, ret = %d\n",
@@ -8480,7 +8589,7 @@ static int wdc_fetch_log_directory(int fd, PWDC_DE_VU_LOG_DIRECTORY directory)
}
fileDirectory = (__u8*)calloc(1, fileDirectorySize);
- ret = wdc_de_VU_read_buffer(fd, 0, 5, 0, fileDirectory, &fileDirectorySize);
+ ret = wdc_de_VU_read_buffer(dev, 0, 5, 0, fileDirectory, &fileDirectorySize);
if (WDC_STATUS_SUCCESS != ret) {
fprintf(stderr,
"ERROR : WDC : %s: Failed to get filesystem directory, ret = %d\n",
@@ -8533,7 +8642,8 @@ end:
return ret;
}
-static int wdc_fetch_log_file_from_device(int fd, __u32 fileId, __u16 spiDestn, __u64 fileSize, __u8* dataBuffer)
+static int wdc_fetch_log_file_from_device(struct nvme_dev *dev, __u32 fileId,
+ __u16 spiDestn, __u64 fileSize, __u8* dataBuffer)
{
int ret = WDC_STATUS_FAILURE;
__u32 chunckSize = WDC_DE_VU_READ_BUFFER_STANDARD_OFFSET;
@@ -8541,13 +8651,13 @@ static int wdc_fetch_log_file_from_device(int fd, __u32 fileId, __u16 spiDestn,
__u32 buffSize = 0;
__u64 offsetIdx = 0;
- if (!fd || !dataBuffer || !fileSize)
+ if (!dev || !dataBuffer || !fileSize)
{
ret = WDC_STATUS_INVALID_PARAMETER;
goto end;
}
- if (wdc_get_max_transfer_len(fd, &maximumTransferLength) < 0) {
+ if (wdc_get_max_transfer_len(dev, &maximumTransferLength) < 0) {
ret = WDC_STATUS_FAILURE;
goto end;
}
@@ -8565,7 +8675,7 @@ static int wdc_fetch_log_file_from_device(int fd, __u32 fileId, __u16 spiDestn,
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(fd, fileId, spiDestn,
+ ret = wdc_de_VU_read_buffer(dev, fileId, spiDestn,
(__u32)((offsetIdx * chunckSize) / sizeof(__u32)), dataBuffer + (offsetIdx * chunckSize), &buffSize);
if (ret != WDC_STATUS_SUCCESS)
{
@@ -8576,7 +8686,7 @@ static int wdc_fetch_log_file_from_device(int fd, __u32 fileId, __u16 spiDestn,
}
} else {
buffSize = (__u32)fileSize;
- ret = wdc_de_VU_read_buffer(fd, fileId, spiDestn,
+ ret = wdc_de_VU_read_buffer(dev, fileId, spiDestn,
(__u32)((offsetIdx * chunckSize) / sizeof(__u32)), dataBuffer, &buffSize);
if (ret != WDC_STATUS_SUCCESS)
{
@@ -8589,7 +8699,7 @@ static int wdc_fetch_log_file_from_device(int fd, __u32 fileId, __u16 spiDestn,
return ret;
}
-static int wdc_de_get_dump_trace(int fd, char * filePath, __u16 binFileNameLen, char *binFileName)
+static int wdc_de_get_dump_trace(struct nvme_dev *dev, char * filePath, __u16 binFileNameLen, char *binFileName)
{
int ret = WDC_STATUS_FAILURE;
__u8 *readBuffer = NULL;
@@ -8604,19 +8714,19 @@ static int wdc_de_get_dump_trace(int fd, char * filePath, __u16 binFileNameLen,
__u16 i = 0;
__u32 maximumTransferLength = 0;
- if (!fd || !binFileName || !filePath)
+ if (!dev || !binFileName || !filePath)
{
ret = WDC_STATUS_INVALID_PARAMETER;
return ret;
}
- if (wdc_get_max_transfer_len(fd, &maximumTransferLength) < 0)
+ if (wdc_get_max_transfer_len(dev, &maximumTransferLength) < 0)
return WDC_STATUS_FAILURE;
do
{
/* Get dumptrace size */
- ret = wdc_de_VU_read_size(fd, 0, WDC_DE_DUMPTRACE_DESTINATION, &dumptraceSize);
+ ret = wdc_de_VU_read_size(dev, 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",
@@ -8665,7 +8775,7 @@ static int wdc_de_get_dump_trace(int fd, char * filePath, __u16 binFileNameLen,
readBufferLen = lastPktReadBufferLen;
}
- ret = wdc_de_VU_read_buffer(fd, 0, WDC_DE_DUMPTRACE_DESTINATION, 0, readBuffer + offset, &readBufferLen);
+ ret = wdc_de_VU_read_buffer(dev, 0, WDC_DE_DUMPTRACE_DESTINATION, 0, readBuffer + offset, &readBufferLen);
if (ret != WDC_STATUS_SUCCESS)
{
fprintf(stderr, "ERROR : WDC : %s: wdc_de_VU_read_buffer failed, ret = %d on offset 0x%x\n",
@@ -8692,7 +8802,8 @@ static int wdc_de_get_dump_trace(int fd, char * filePath, __u16 binFileNameLen,
return ret;
}
-static int wdc_do_drive_essentials(nvme_root_t r, int fd, char *dir, char *key)
+static int wdc_do_drive_essentials(nvme_root_t r, struct nvme_dev *dev,
+ char *dir, char *key)
{
int ret = 0;
void *retPtr;
@@ -8732,7 +8843,7 @@ static int wdc_do_drive_essentials(nvme_root_t r, int fd, char *dir, char *key)
memset(tarCmd,0,sizeof(tarCmd));
memset(&timeInfo,0,sizeof(timeInfo));
- if (wdc_get_serial_and_fw_rev(fd, (char *)idSerialNo, (char *)idFwRev))
+ if (wdc_get_serial_and_fw_rev(dev, (char *)idSerialNo, (char *)idFwRev))
{
fprintf(stderr, "ERROR : WDC : get serial # and fw revision failed\n");
return -1;
@@ -8785,7 +8896,7 @@ static int wdc_do_drive_essentials(nvme_root_t r, int fd, char *dir, char *key)
/* Get Identify Controller Data */
memset(&ctrl, 0, sizeof (struct nvme_id_ctrl));
- ret = nvme_identify_ctrl(fd, &ctrl);
+ ret = nvme_identify_ctrl(dev_fd(dev), &ctrl);
if (ret) {
fprintf(stderr, "ERROR : WDC : nvme_identify_ctrl() failed, ret = %d\n", ret);
return -1;
@@ -8796,7 +8907,7 @@ static int wdc_do_drive_essentials(nvme_root_t r, int fd, char *dir, char *key)
}
memset(&ns, 0, sizeof (struct nvme_id_ns));
- ret = nvme_identify_ns(fd, 1, &ns);
+ ret = nvme_identify_ns(dev_fd(dev), 1, &ns);
if (ret) {
fprintf(stderr, "ERROR : WDC : nvme_identify_ns() failed, ret = %d\n", ret);
} else {
@@ -8811,7 +8922,8 @@ static int wdc_do_drive_essentials(nvme_root_t r, int fd, char *dir, char *key)
dataBuffer = calloc(1, elogBufferSize);
elogBuffer = (struct nvme_error_log_page *)dataBuffer;
- ret = nvme_get_log_error(fd, elogNumEntries, false, elogBuffer);
+ ret = nvme_get_log_error(dev_fd(dev), elogNumEntries, false,
+ elogBuffer);
if (ret) {
fprintf(stderr, "ERROR : WDC : nvme_error_log() failed, ret = %d\n", ret);
} else {
@@ -8825,7 +8937,8 @@ static int wdc_do_drive_essentials(nvme_root_t r, int fd, char *dir, char *key)
/* Get Smart log page */
memset(&smart_log, 0, sizeof (struct nvme_smart_log));
- ret = nvme_get_log_smart(fd, NVME_NSID_ALL, false, &smart_log);
+ ret = nvme_get_log_smart(dev_fd(dev), NVME_NSID_ALL, false,
+ &smart_log);
if (ret) {
fprintf(stderr, "ERROR : WDC : nvme_smart_log() failed, ret = %d\n", ret);
} else {
@@ -8836,7 +8949,7 @@ static int wdc_do_drive_essentials(nvme_root_t r, int fd, char *dir, char *key)
/* Get FW Slot log page */
memset(&fw_log, 0, sizeof (struct nvme_firmware_slot));
- ret = nvme_get_log_fw_slot(fd, false, &fw_log);
+ ret = nvme_get_log_fw_slot(dev_fd(dev), false, &fw_log);
if (ret) {
fprintf(stderr, "ERROR : WDC : nvme_fw_log() failed, ret = %d\n", ret);
} else {
@@ -8856,8 +8969,9 @@ static int wdc_do_drive_essentials(nvme_root_t r, int fd, char *dir, char *key)
dataBuffer = calloc(1, dataBufferSize);
memset(dataBuffer, 0, dataBufferSize);
- ret = nvme_get_log_simple(fd, deVULogPagesList[vuLogIdx].logPageId,
- dataBufferSize, dataBuffer);
+ ret = nvme_get_log_simple(dev_fd(dev),
+ deVULogPagesList[vuLogIdx].logPageId,
+ dataBufferSize, dataBuffer);
if (ret) {
fprintf(stderr, "ERROR : WDC : nvme_get_log() for log page 0x%x failed, ret = %d\n",
deVULogPagesList[vuLogIdx].logPageId, ret);
@@ -8881,8 +8995,11 @@ static int wdc_do_drive_essentials(nvme_root_t r, int fd, char *dir, char *key)
/* 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(fd, deFeatureIdList[listIdx].featureId, WDC_DE_GLOBAL_NSID,
- sizeof(featureIdBuff), &featureIdBuff, &result);
+ ret = nvme_get_features_data(dev_fd(dev),
+ (enum nvme_features_id)deFeatureIdList[listIdx].featureId,
+ WDC_DE_GLOBAL_NSID,
+ sizeof(featureIdBuff),
+ &featureIdBuff, &result);
if (ret) {
fprintf(stderr, "ERROR : WDC : nvme_get_feature id 0x%x failed, ret = %d\n",
@@ -8896,7 +9013,7 @@ static int wdc_do_drive_essentials(nvme_root_t r, int fd, char *dir, char *key)
}
/* Read Debug Directory */
- ret = wdc_get_log_dir_max_entries(fd, &maxNumOfVUFiles);
+ ret = wdc_get_log_dir_max_entries(dev, &maxNumOfVUFiles);
if (ret == WDC_STATUS_SUCCESS)
{
memset(&deEssentialsList, 0, sizeof(deEssentialsList));
@@ -8904,7 +9021,7 @@ static int wdc_do_drive_essentials(nvme_root_t r, int fd, char *dir, char *key)
deEssentialsList.maxNumLogEntries = maxNumOfVUFiles;
/* Fetch VU File Directory */
- ret = wdc_fetch_log_directory(fd, &deEssentialsList);
+ ret = wdc_fetch_log_directory(dev, &deEssentialsList);
if (ret == WDC_STATUS_SUCCESS)
{
/* Get Debug Data Files */
@@ -8918,7 +9035,7 @@ static int wdc_do_drive_essentials(nvme_root_t r, int fd, char *dir, char *key)
} else {
/* Fetch Log File Data */
dataBuffer = (char *)calloc(1, (size_t)deEssentialsList.logEntry[listIdx].metaData.fileSize);
- ret = wdc_fetch_log_file_from_device(fd, deEssentialsList.logEntry[listIdx].metaData.fileID, WDC_DE_DESTN_SPI, deEssentialsList.logEntry[listIdx].metaData.fileSize,
+ ret = wdc_fetch_log_file_from_device(dev, deEssentialsList.logEntry[listIdx].metaData.fileID, WDC_DE_DESTN_SPI, deEssentialsList.logEntry[listIdx].metaData.fileSize,
(__u8 *)dataBuffer);
/* Write databuffer to file */
@@ -8954,7 +9071,7 @@ static int wdc_do_drive_essentials(nvme_root_t r, int fd, char *dir, char *key)
/* 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);
- if (WDC_STATUS_SUCCESS != (ret = wdc_de_get_dump_trace(fd, (char*)bufferFolderPath, 0, fileName)))
+ if (WDC_STATUS_SUCCESS != (ret = wdc_de_get_dump_trace(dev, (char*)bufferFolderPath, 0, fileName)))
{
fprintf(stderr, "ERROR : WDC : wdc_de_get_dump_trace failed, ret = %d\n", ret);
}
@@ -8987,10 +9104,11 @@ static int wdc_drive_essentials(int argc, char **argv, struct command *command,
char *dirName = "Output directory pathname.";
char d[PATH_MAX] = {0};
char k[PATH_MAX] = {0};
- char *d_ptr;
- int fd, ret;
- nvme_root_t r;
__u64 capabilities = 0;
+ struct nvme_dev *dev;
+ nvme_root_t r;
+ char *d_ptr;
+ int ret;
struct config {
char *dirName;
@@ -9006,12 +9124,12 @@ static int wdc_drive_essentials(int argc, char **argv, struct command *command,
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
+ if (ret)
+ return ret;
r = nvme_scan(NULL);
- capabilities = wdc_get_drive_capabilities(r, fd);
+ capabilities = wdc_get_drive_capabilities(r, dev);
if ((capabilities & WDC_DRIVE_CAP_DRIVE_ESSENTIALS) != WDC_DRIVE_CAP_DRIVE_ESSENTIALS) {
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
ret = -1;
@@ -9025,14 +9143,14 @@ static int wdc_drive_essentials(int argc, char **argv, struct command *command,
d_ptr = NULL;
}
- ret = wdc_do_drive_essentials(r, fd, d_ptr, k);
+ ret = wdc_do_drive_essentials(r, dev, d_ptr, k);
out:
nvme_free_tree(r);
- close(fd);
+ dev_close(dev);
return ret;
}
-static int wdc_do_drive_resize(int fd, uint64_t new_size)
+static int wdc_do_drive_resize(struct nvme_dev *dev, uint64_t new_size)
{
int ret;
struct nvme_passthru_cmd admin_cmd;
@@ -9043,11 +9161,11 @@ static int wdc_do_drive_resize(int fd, uint64_t new_size)
WDC_NVME_DRIVE_RESIZE_CMD);
admin_cmd.cdw13 = new_size;
- ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL);
+ ret = nvme_submit_admin_passthru(dev_fd(dev), &admin_cmd, NULL);
return ret;
}
-static int wdc_do_namespace_resize(int fd, __u32 nsid, __u32 op_option)
+static int wdc_do_namespace_resize(struct nvme_dev *dev, __u32 nsid, __u32 op_option)
{
int ret;
struct nvme_passthru_cmd admin_cmd;
@@ -9057,11 +9175,11 @@ static int wdc_do_namespace_resize(int fd, __u32 nsid, __u32 op_option)
admin_cmd.nsid = nsid;
admin_cmd.cdw10 = op_option;
- ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL);
+ ret = nvme_submit_admin_passthru(dev_fd(dev), &admin_cmd, NULL);
return ret;
}
-static int wdc_do_drive_info(int fd, __u32 *result)
+static int wdc_do_drive_info(struct nvme_dev *dev, __u32 *result)
{
int ret;
struct nvme_passthru_cmd admin_cmd;
@@ -9071,7 +9189,7 @@ static int wdc_do_drive_info(int fd, __u32 *result)
admin_cmd.cdw12 = ((WDC_NVME_DRIVE_INFO_SUBCMD << WDC_NVME_SUBCMD_SHIFT) |
WDC_NVME_DRIVE_INFO_CMD);
- ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL);
+ ret = nvme_submit_admin_passthru(dev_fd(dev), &admin_cmd, NULL);
if (!ret && result)
*result = admin_cmd.result;
@@ -9084,9 +9202,10 @@ 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.";
- nvme_root_t r;
uint64_t capabilities = 0;
- int fd, ret;
+ struct nvme_dev *dev;
+ nvme_root_t r;
+ int ret;
struct config {
uint64_t size;
@@ -9101,15 +9220,15 @@ static int wdc_drive_resize(int argc, char **argv,
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
+ if (ret)
+ return ret;
r = nvme_scan(NULL);
- wdc_check_device(r, fd);
- capabilities = wdc_get_drive_capabilities(r, fd);
+ wdc_check_device(r, dev);
+ capabilities = wdc_get_drive_capabilities(r, dev);
if ((capabilities & WDC_DRIVE_CAP_RESIZE) == WDC_DRIVE_CAP_RESIZE) {
- ret = wdc_do_drive_resize(fd, cfg.size);
+ ret = wdc_do_drive_resize(dev, cfg.size);
} else {
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
ret = -1;
@@ -9120,7 +9239,7 @@ static int wdc_drive_resize(int argc, char **argv,
nvme_show_status(ret);
nvme_free_tree(r);
- close(fd);
+ dev_close(dev);
return ret;
}
@@ -9130,9 +9249,10 @@ 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.";
- nvme_root_t r;
uint64_t capabilities = 0;
- int fd, ret;
+ struct nvme_dev *dev;
+ nvme_root_t r;
+ int ret;
struct config {
__u32 namespace_id;
@@ -9150,9 +9270,9 @@ static int wdc_namespace_resize(int argc, char **argv,
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
+ if (ret)
+ return ret;
if ((cfg.op_option != 0x1) &&
(cfg.op_option != 0x2) &&
@@ -9160,15 +9280,16 @@ static int wdc_namespace_resize(int argc, char **argv,
(cfg.op_option != 0xF))
{
fprintf(stderr, "ERROR : WDC: unsupported OP option parameter\n");
- close(fd);
+ dev_close(dev);
return -1;
}
r = nvme_scan(NULL);
- wdc_check_device(r, fd);
- capabilities = wdc_get_drive_capabilities(r, fd);
+ wdc_check_device(r, dev);
+ capabilities = wdc_get_drive_capabilities(r, dev);
if ((capabilities & WDC_DRIVE_CAP_NS_RESIZE) == WDC_DRIVE_CAP_NS_RESIZE) {
- ret = wdc_do_namespace_resize(fd, cfg.namespace_id, cfg.op_option);
+ ret = wdc_do_namespace_resize(dev, cfg.namespace_id,
+ cfg.op_option);
if (ret != 0)
printf("ERROR : WDC: Namespace Resize of namespace id 0x%x, op option 0x%x failed\n", cfg.namespace_id, cfg.op_option);
@@ -9179,7 +9300,7 @@ static int wdc_namespace_resize(int argc, char **argv,
nvme_show_status(ret);
nvme_free_tree(r);
- close(fd);
+ dev_close(dev);
return ret;
}
@@ -9189,8 +9310,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;
- int fd;
int ret;
uint64_t capabilities = 0;
char f[PATH_MAX] = {0};
@@ -9214,10 +9335,10 @@ static int wdc_reason_identifier(int argc, char **argv,
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ if (ret)
+ return ret;
r = nvme_scan(NULL);
@@ -9250,7 +9371,7 @@ 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(fd, f, PATH_MAX, fileSuffix) == -1) {
+ if (wdc_get_serial_name(dev, f, PATH_MAX, fileSuffix) == -1) {
fprintf(stderr, "ERROR : WDC: failed to generate file name\n");
ret = -1;
goto close_fd;
@@ -9265,9 +9386,9 @@ static int wdc_reason_identifier(int argc, char **argv,
fprintf(stderr, "%s: filename = %s\n", __func__, f);
- capabilities = wdc_get_drive_capabilities(r, fd);
+ capabilities = wdc_get_drive_capabilities(r, dev);
if ((capabilities & WDC_DRIVE_CAP_REASON_ID) == WDC_DRIVE_CAP_REASON_ID) {
- ret = wdc_do_get_reason_id(fd, f, cfg.log_id);
+ ret = wdc_do_get_reason_id(dev, f, cfg.log_id);
} else {
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
ret = -1;
@@ -9276,7 +9397,7 @@ static int wdc_reason_identifier(int argc, char **argv,
nvme_show_status(ret);
close_fd:
- close(fd);
+ dev_close(dev);
nvme_free_tree(r);
return ret;
}
@@ -9328,7 +9449,7 @@ static int wdc_log_page_directory(int argc, char **argv, struct command *command
struct plugin *plugin)
{
const char *desc = "Retrieve Log Page Directory.";
- int fd;
+ struct nvme_dev *dev;
int ret = 0;
nvme_root_t r;
__u64 capabilities = 0;
@@ -9350,36 +9471,36 @@ static int wdc_log_page_directory(int argc, char **argv, struct command *command
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
+ if (ret)
+ return ret;
ret = validate_output_format(cfg.output_format);
if (ret < 0) {
fprintf(stderr, "%s: ERROR : WDC : invalid output format\n", __func__);
- close(fd);
+ dev_close(dev);
return ret;
}
ret = 0;
r = nvme_scan(NULL);
- capabilities = wdc_get_drive_capabilities(r, fd);
+ capabilities = wdc_get_drive_capabilities(r, dev);
if ((capabilities & WDC_DRIVE_CAP_LOG_PAGE_DIR) == 0) {
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
ret = -1;
} else {
- ret = wdc_get_pci_ids(r, &device_id, &read_vendor_id);
+ ret = wdc_get_pci_ids(r, dev, &device_id, &read_vendor_id);
log_id = (device_id == WDC_NVME_ZN350_DEV_ID || device_id == WDC_NVME_ZN350_DEV_ID_1) ?
WDC_NVME_GET_DEV_MGMNT_LOG_PAGE_OPCODE_C8 : WDC_NVME_GET_DEV_MGMNT_LOG_PAGE_OPCODE;
/* verify the 0xC2 Device Manageability log page is supported */
- if (wdc_nvme_check_supported_log_page(r, fd, log_id) == false) {
+ if (wdc_nvme_check_supported_log_page(r, dev, log_id) == false) {
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, fd, WDC_C2_LOG_PAGES_SUPPORTED_ID, (void *)&cbs_data)) {
+ if (get_dev_mgment_cbs_data(r, dev, WDC_C2_LOG_PAGES_SUPPORTED_ID, (void *)&cbs_data)) {
if (cbs_data != NULL) {
printf("Log Page Directory\n");
/* print the supported pages */
@@ -9416,11 +9537,11 @@ static int wdc_log_page_directory(int argc, char **argv, struct command *command
out:
nvme_free_tree(r);
- close(fd);
+ dev_close(dev);
return ret;
}
-static int wdc_get_drive_reason_id(int fd, char *drive_reason_id, size_t len)
+static int wdc_get_drive_reason_id(struct nvme_dev *dev, char *drive_reason_id, size_t len)
{
int i, j;
int ret;
@@ -9432,7 +9553,7 @@ static int wdc_get_drive_reason_id(int fd, char *drive_reason_id, size_t len)
j = sizeof (ctrl.mn) - 1;
memset(drive_reason_id, 0, len);
memset(&ctrl, 0, sizeof (struct nvme_id_ctrl));
- ret = nvme_identify_ctrl(fd, &ctrl);
+ ret = nvme_identify_ctrl(dev_fd(dev), &ctrl);
if (ret) {
fprintf(stderr, "ERROR : WDC : nvme_identify_ctrl() failed "
"0x%x\n", ret);
@@ -9459,7 +9580,7 @@ static int wdc_get_drive_reason_id(int fd, char *drive_reason_id, size_t len)
return 0;
}
-static int wdc_save_reason_id(int fd, __u8 *rsn_ident, int size)
+static int wdc_save_reason_id(struct nvme_dev *dev, __u8 *rsn_ident, int size)
{
int ret = 0;
char *reason_id_file;
@@ -9467,7 +9588,7 @@ static int wdc_save_reason_id(int fd, __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(fd, drive_reason_id, PATH_MAX) == -1) {
+ if (wdc_get_drive_reason_id(dev, drive_reason_id, PATH_MAX) == -1) {
fprintf(stderr, "%s: ERROR : failed to get drive reason id\n", __func__);
return -1;
}
@@ -9494,14 +9615,14 @@ static int wdc_save_reason_id(int fd, __u8 *rsn_ident, int size)
return ret;
}
-static int wdc_clear_reason_id(int fd)
+static int wdc_clear_reason_id(struct nvme_dev *dev)
{
int ret = -1;
int verify_file;
char *reason_id_file;
char drive_reason_id[PATH_MAX] = {0};
- if (wdc_get_drive_reason_id(fd, drive_reason_id, PATH_MAX) == -1) {
+ if (wdc_get_drive_reason_id(dev, drive_reason_id, PATH_MAX) == -1) {
fprintf(stderr, "%s: ERROR : failed to get drive reason id\n", __func__);
return -1;
}
@@ -9527,14 +9648,15 @@ static int wdc_clear_reason_id(int fd)
return ret;
}
-static int wdc_dump_telemetry_hdr(int fd, int log_id, struct nvme_telemetry_log *log_hdr)
+static int wdc_dump_telemetry_hdr(struct nvme_dev *dev, 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(fd, log_hdr);
+ ret = nvme_get_log_create_telemetry_host(dev_fd(dev), log_hdr);
else
- ret = nvme_get_log_telemetry_ctrl(fd, false, 0, 512, (void *)log_hdr);
+ ret = nvme_get_log_telemetry_ctrl(dev_fd(dev), false, 0, 512,
+ (void *)log_hdr);
if (ret < 0)
perror("get-telemetry-log");
@@ -9546,7 +9668,7 @@ static int wdc_dump_telemetry_hdr(int fd, int log_id, struct nvme_telemetry_log
return ret;
}
-static int wdc_do_get_reason_id(int fd, char *file, int log_id)
+static int wdc_do_get_reason_id(struct nvme_dev *dev, char *file, int log_id)
{
int ret;
struct nvme_telemetry_log *log_hdr;
@@ -9561,7 +9683,7 @@ static int wdc_do_get_reason_id(int fd, char *file, int log_id)
}
memset(log_hdr, 0, log_hdr_size);
- ret = wdc_dump_telemetry_hdr(fd, log_id, log_hdr);
+ ret = wdc_dump_telemetry_hdr(dev, log_id, log_hdr);
if (ret != 0) {
fprintf(stderr, "%s: ERROR : get telemetry header failed, ret : %d\n", __func__, ret);
ret = -1;
@@ -9571,7 +9693,7 @@ static int wdc_do_get_reason_id(int fd, char *file, int log_id)
reason_id_size = sizeof(log_hdr->rsnident);
if (log_id == NVME_LOG_LID_TELEMETRY_CTRL)
- wdc_save_reason_id(fd, log_hdr->rsnident, reason_id_size);
+ wdc_save_reason_id(dev, log_hdr->rsnident, reason_id_size);
ret = wdc_create_log_file(file, (__u8 *)log_hdr->rsnident, reason_id_size);
@@ -9592,10 +9714,12 @@ static void wdc_print_nand_stats_normal(__u16 version, void *data)
{
case 0:
printf(" NAND Statistics :- \n");
- printf(" NAND Writes TLC (Bytes) %.0Lf\n",
- int128_to_double(nand_stats->nand_write_tlc));
- printf(" NAND Writes SLC (Bytes) %.0Lf\n",
- int128_to_double(nand_stats->nand_write_slc));
+ printf(" NAND Writes TLC (Bytes) %s\n",
+ uint128_t_to_string(
+ le128_to_cpu(nand_stats->nand_write_tlc)));
+ printf(" NAND Writes SLC (Bytes) %s\n",
+ uint128_t_to_string(
+ le128_to_cpu(nand_stats->nand_write_slc)));
printf(" NAND Program Failures %"PRIu32"\n",
(uint32_t)le32_to_cpu(nand_stats->nand_prog_failure));
printf(" NAND Erase Failures %"PRIu32"\n",
@@ -9613,10 +9737,12 @@ static void wdc_print_nand_stats_normal(__u16 version, void *data)
break;
case 3:
printf(" NAND Statistics V3:- \n");
- printf(" TLC Units Written %.0Lf\n",
- int128_to_double(nand_stats_v3->nand_write_tlc));
- printf(" SLC Units Written %.0Lf\n",
- int128_to_double(nand_stats_v3->nand_write_slc));
+ printf(" TLC Units Written %s\n",
+ uint128_t_to_string(
+ le128_to_cpu(nand_stats_v3->nand_write_tlc)));
+ printf(" SLC Units Written %s\n",
+ uint128_t_to_string(
+ le128_to_cpu(nand_stats_v3->nand_write_slc)));
temp_ptr = (__u64 *)nand_stats_v3->bad_nand_block_count;
temp_norm = (__u16)(*temp_ptr & 0x000000000000FFFF);
temp_raw = ((*temp_ptr & 0xFFFFFFFFFFFF0000) >> 16);
@@ -9666,8 +9792,9 @@ static void wdc_print_nand_stats_normal(__u16 version, void *data)
le64_to_cpu(nand_stats_v3->security_version_number));
printf(" %% Free Blocks (System) %u\n",
nand_stats_v3->percent_free_blocks_system);
- printf(" Data Set Management Commands %.0Lf\n",
- int128_to_double(nand_stats_v3->trim_completions));
+ printf(" Data Set Management Commands %s\n",
+ uint128_t_to_string(
+ le128_to_cpu(nand_stats_v3->trim_completions)));
printf(" Estimate of Incomplete Trim Data %"PRIu64"\n",
le64_to_cpu(nand_stats_v3->trim_completions[16]));
printf(" %% of completed trim %u\n",
@@ -9685,16 +9812,18 @@ static void wdc_print_nand_stats_normal(__u16 version, void *data)
le16_to_cpu(temp_norm));
printf(" Bad System Nand Block Count - Raw %"PRIu64"\n",
le64_to_cpu(temp_raw));
- printf(" Endurance Estimate %.0Lf\n",
- int128_to_double(nand_stats_v3->endurance_estimate));
+ printf(" Endurance Estimate %s\n",
+ uint128_t_to_string(
+ le128_to_cpu(nand_stats_v3->endurance_estimate)));
printf(" Thermal Throttling Count %u\n",
nand_stats_v3->thermal_throttling_st_ct[0]);
printf(" Thermal Throttling Status %u\n",
nand_stats_v3->thermal_throttling_st_ct[1]);
printf(" Unaligned I/O %"PRIu64"\n",
le64_to_cpu(nand_stats_v3->unaligned_IO));
- printf(" Physical Media Units Read %.0Lf\n",
- int128_to_double(nand_stats_v3->physical_media_units));
+ printf(" Physical Media Units Read %s\n",
+ uint128_t_to_string(
+ le128_to_cpu(nand_stats_v3->physical_media_units)));
printf(" log page version %"PRIu16"\n",
le16_to_cpu(nand_stats_v3->log_page_version));
break;
@@ -9721,10 +9850,10 @@ static void wdc_print_nand_stats_json(__u16 version, void *data)
case 0:
- json_object_add_value_double(root, "NAND Writes TLC (Bytes)",
- int128_to_double(nand_stats->nand_write_tlc));
- json_object_add_value_double(root, "NAND Writes SLC (Bytes)",
- int128_to_double(nand_stats->nand_write_slc));
+ json_object_add_value_uint128(root, "NAND Writes TLC (Bytes)",
+ le128_to_cpu(nand_stats->nand_write_tlc));
+ json_object_add_value_uint128(root, "NAND Writes SLC (Bytes)",
+ le128_to_cpu(nand_stats->nand_write_slc));
json_object_add_value_uint(root, "NAND Program Failures",
le32_to_cpu(nand_stats->nand_prog_failure));
json_object_add_value_uint(root, "NAND Erase Failures",
@@ -9744,10 +9873,10 @@ static void wdc_print_nand_stats_json(__u16 version, void *data)
case 3:
- json_object_add_value_double(root, "NAND Writes TLC (Bytes)",
- int128_to_double(nand_stats_v3->nand_write_tlc));
- json_object_add_value_double(root, "NAND Writes SLC (Bytes)",
- int128_to_double(nand_stats_v3->nand_write_slc));
+ json_object_add_value_uint128(root, "NAND Writes TLC (Bytes)",
+ le128_to_cpu(nand_stats_v3->nand_write_tlc));
+ json_object_add_value_uint128(root, "NAND Writes SLC (Bytes)",
+ le128_to_cpu(nand_stats_v3->nand_write_slc));
temp_ptr = (__u64 *)nand_stats_v3->bad_nand_block_count;
temp_norm = (__u16)(*temp_ptr & 0x000000000000FFFF);
temp_raw = ((*temp_ptr & 0xFFFFFFFFFFFF0000) >> 16);
@@ -9797,8 +9926,8 @@ static void wdc_print_nand_stats_json(__u16 version, void *data)
le64_to_cpu(nand_stats_v3->security_version_number));
json_object_add_value_uint(root, "% Free Blocks (System)",
nand_stats_v3->percent_free_blocks_system);
- json_object_add_value_double(root, "Data Set Management Commands",
- int128_to_double(nand_stats_v3->trim_completions));
+ json_object_add_value_uint128(root, "Data Set Management Commands",
+ le128_to_cpu(nand_stats_v3->trim_completions));
json_object_add_value_uint64(root, "Estimate of Incomplete Trim Data",
le64_to_cpu(nand_stats_v3->trim_completions[16]));
json_object_add_value_uint(root, "%% of completed trim",
@@ -9816,16 +9945,16 @@ static void wdc_print_nand_stats_json(__u16 version, void *data)
le16_to_cpu(temp_norm));
json_object_add_value_uint64(root, "Bad System Nand Block Count - Raw",
le64_to_cpu(temp_raw));
- json_object_add_value_double(root, "Endurance Estimate",
- int128_to_double(nand_stats_v3->endurance_estimate));
+ json_object_add_value_uint128(root, "Endurance Estimate",
+ le128_to_cpu(nand_stats_v3->endurance_estimate));
json_object_add_value_uint(root, "Thermal Throttling Status",
nand_stats_v3->thermal_throttling_st_ct[0]);
json_object_add_value_uint(root, "Thermal Throttling Count",
nand_stats_v3->thermal_throttling_st_ct[1]);
json_object_add_value_uint64(root, "Unaligned I/O",
le64_to_cpu(nand_stats_v3->unaligned_IO));
- json_object_add_value_double(root, "Physical Media Units Read",
- int128_to_double(nand_stats_v3->physical_media_units));
+ json_object_add_value_uint128(root, "Physical Media Units Read",
+ le128_to_cpu(nand_stats_v3->physical_media_units));
json_object_add_value_uint(root, "log page version",
le16_to_cpu(nand_stats_v3->log_page_version));
@@ -9926,14 +10055,15 @@ 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(int fd, char *format)
+static int wdc_do_vs_nand_stats_sn810_2(struct nvme_dev *dev, char *format)
{
int ret;
int fmt = -1;
uint8_t *data = NULL;
data = NULL;
- ret = nvme_get_ext_smart_cloud_log(fd, &data, 0, NVME_NSID_ALL);
+ ret = nvme_get_ext_smart_cloud_log(dev_fd(dev), &data, 0,
+ NVME_NSID_ALL);
if (ret) {
fprintf(stderr, "ERROR : WDC : %s : Failed to retreive NAND stats\n", __func__);
@@ -9963,7 +10093,7 @@ out:
return ret;
}
-static int wdc_do_vs_nand_stats(int fd, char *format)
+static int wdc_do_vs_nand_stats(struct nvme_dev *dev, char *format)
{
int ret;
int fmt = -1;
@@ -9976,8 +10106,8 @@ static int wdc_do_vs_nand_stats(int fd, char *format)
goto out;
}
- ret = nvme_get_log_simple(fd, WDC_NVME_NAND_STATS_LOG_ID,
- WDC_NVME_NAND_STATS_SIZE, (void*)output);
+ ret = nvme_get_log_simple(dev_fd(dev), WDC_NVME_NAND_STATS_LOG_ID,
+ WDC_NVME_NAND_STATS_SIZE, (void*)output);
if (ret) {
fprintf(stderr, "ERROR : WDC : %s : Failed to retreive NAND stats\n", __func__);
goto out;
@@ -10011,12 +10141,11 @@ static int wdc_vs_nand_stats(int argc, char **argv, struct command *command,
struct plugin *plugin)
{
const char *desc = "Retrieve NAND statistics.";
-
- int fd;
- int ret = 0;
+ struct nvme_dev *dev;
nvme_root_t r;
__u64 capabilities = 0;
uint32_t read_device_id = 0, read_vendor_id = 0;
+ int ret;
struct config {
char *output_format;
@@ -10031,18 +10160,18 @@ static int wdc_vs_nand_stats(int argc, char **argv, struct command *command,
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
+ if (ret)
+ return ret;
r = nvme_scan(NULL);
- capabilities = wdc_get_drive_capabilities(r, fd);
+ capabilities = wdc_get_drive_capabilities(r, dev);
if ((capabilities & WDC_DRIVE_CAP_NAND_STATS) == 0) {
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
ret = -1;
} else {
- ret = wdc_get_pci_ids(r, &read_device_id, &read_vendor_id);
+ ret = wdc_get_pci_ids(r, dev, &read_device_id, &read_vendor_id);
if (ret < 0)
{
fprintf(stderr, "ERROR : WDC: %s: failure to get pci ids, ret = %d\n", __func__, ret);
@@ -10051,10 +10180,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(fd, cfg.output_format);
+ ret = wdc_do_vs_nand_stats_sn810_2(dev,
+ cfg.output_format);
break;
default:
- ret = wdc_do_vs_nand_stats(fd, cfg.output_format);
+ ret = wdc_do_vs_nand_stats(dev, cfg.output_format);
break;
}
}
@@ -10063,11 +10193,11 @@ static int wdc_vs_nand_stats(int argc, char **argv, struct command *command,
fprintf(stderr, "ERROR : WDC : Failure reading NAND statistics, ret = %d\n", ret);
nvme_free_tree(r);
- close(fd);
+ dev_close(dev);
return ret;
}
-static int wdc_do_vs_pcie_stats(int fd,
+static int wdc_do_vs_pcie_stats(struct nvme_dev *dev,
struct wdc_vs_pcie_stats *pcieStatsPtr)
{
int ret;
@@ -10079,7 +10209,7 @@ static int wdc_do_vs_pcie_stats(int fd,
admin_cmd.addr = (__u64)(uintptr_t)pcieStatsPtr;
admin_cmd.data_len = pcie_stats_size;
- ret = nvme_submit_admin_passthru(fd, &admin_cmd, NULL);
+ ret = nvme_submit_admin_passthru(dev_fd(dev), &admin_cmd, NULL);
return ret;
}
@@ -10088,8 +10218,7 @@ static int wdc_vs_pcie_stats(int argc, char **argv, struct command *command,
struct plugin *plugin)
{
const char *desc = "Retrieve PCIE statistics.";
-
- int fd;
+ struct nvme_dev *dev;
int ret = 0;
nvme_root_t r;
__u64 capabilities = 0;
@@ -10111,9 +10240,9 @@ static int wdc_vs_pcie_stats(int argc, char **argv, struct command *command,
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
+ if (ret)
+ return ret;
r = nvme_scan(NULL);
@@ -10133,13 +10262,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, fd);
+ capabilities = wdc_get_drive_capabilities(r, dev);
if ((capabilities & WDC_DRIVE_CAP_PCIE_STATS) == 0) {
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
ret = -1;
} else {
- ret = wdc_do_vs_pcie_stats(fd, pcieStatsPtr);
+ ret = wdc_do_vs_pcie_stats(dev, pcieStatsPtr);
if (ret)
fprintf(stderr, "ERROR : WDC : Failure reading PCIE statistics, ret = 0x%x\n", ret);
else {
@@ -10159,7 +10288,7 @@ static int wdc_vs_pcie_stats(int argc, char **argv, struct command *command,
out:
nvme_free_tree(r);
- close(fd);
+ dev_close(dev);
return ret;
}
@@ -10169,7 +10298,8 @@ static int wdc_vs_drive_info(int argc, char **argv,
const char *desc = "Send a vs-drive-info command.";
nvme_root_t r;
uint64_t capabilities = 0;
- int fd, ret;
+ struct nvme_dev *dev;
+ int ret;
__le32 result;
__u16 size;
double rev;
@@ -10199,31 +10329,31 @@ static int wdc_vs_drive_info(int argc, char **argv,
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
+ if (ret)
+ return ret;
fmt = validate_output_format(cfg.output_format);
if (fmt < 0) {
fprintf(stderr, "ERROR : WDC %s invalid output format\n", __func__);
- close(fd);
+ dev_close(dev);
return fmt;
}
/* get the id ctrl data used to fill in drive info below */
- ret = nvme_identify_ctrl(fd, &ctrl);
+ ret = nvme_identify_ctrl(dev_fd(dev), &ctrl);
if (ret) {
fprintf(stderr, "ERROR : WDC %s: Identify Controller failed\n", __func__);
- close(fd);
+ dev_close(dev);
return ret;
}
r = nvme_scan(NULL);
- wdc_check_device(r, fd);
- capabilities = wdc_get_drive_capabilities(r, fd);
+ wdc_check_device(r, dev);
+ capabilities = wdc_get_drive_capabilities(r, dev);
if ((capabilities & WDC_DRIVE_CAP_INFO) == WDC_DRIVE_CAP_INFO) {
- ret = wdc_get_pci_ids(r, &read_device_id, &read_vendor_id);
+ ret = wdc_get_pci_ids(r, dev, &read_device_id, &read_vendor_id);
if (ret < 0)
{
fprintf(stderr, "ERROR : WDC: %s: failure to get pci ids, ret = %d\n", __func__, ret);
@@ -10247,7 +10377,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(fd, &result);
+ ret = wdc_do_drive_info(dev, &result);
if (!ret) {
size = (__u16)((cpu_to_le32(result) & 0xffff0000) >> 16);
@@ -10299,7 +10429,8 @@ 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(fd, &data, 0, NVME_NSID_ALL);
+ ret = nvme_get_hw_rev_log(dev_fd(dev), &data, 0,
+ NVME_NSID_ALL);
if (ret == 0) {
wdc_nvme_hw_rev_log *log_data = (wdc_nvme_hw_rev_log *)data;
major_rev = log_data->hw_rev_gdr;
@@ -10319,7 +10450,8 @@ static int wdc_vs_drive_info(int argc, char **argv,
goto out;
}
- ret = nvme_get_ext_smart_cloud_log(fd, &data, 0, NVME_NSID_ALL);
+ ret = nvme_get_ext_smart_cloud_log(dev_fd(dev), &data,
+ 0, NVME_NSID_ALL);
if (ret == 0) {
ext_smart_log_ptr = (wdc_nvme_ext_smart_log *)data;
@@ -10376,7 +10508,7 @@ static int wdc_vs_drive_info(int argc, char **argv,
out:
nvme_show_status(ret);
nvme_free_tree(r);
- close(fd);
+ dev_close(dev);
return ret;
}
@@ -10386,12 +10518,12 @@ static int wdc_vs_temperature_stats(int argc, char **argv,
const char *desc = "Send a vs-temperature-stats command.";
struct nvme_smart_log smart_log;
struct nvme_id_ctrl id_ctrl;
+ struct nvme_dev *dev;
nvme_root_t r;
uint64_t capabilities = 0;
__u32 hctm_tmt;
- int fd, ret;
int temperature, temp_tmt1, temp_tmt2;
- int fmt = -1;
+ int ret, fmt = -1;
struct config {
char *output_format;
@@ -10406,9 +10538,9 @@ static int wdc_vs_temperature_stats(int argc, char **argv,
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
+ if (ret)
+ return ret;
r = nvme_scan(NULL);
fmt = validate_output_format(cfg.output_format);
@@ -10419,8 +10551,8 @@ static int wdc_vs_temperature_stats(int argc, char **argv,
}
/* check if command is supported */
- wdc_check_device(r, fd);
- capabilities = wdc_get_drive_capabilities(r, fd);
+ wdc_check_device(r, dev);
+ capabilities = wdc_get_drive_capabilities(r, dev);
if ((capabilities & WDC_DRIVE_CAP_TEMP_STATS) != WDC_DRIVE_CAP_TEMP_STATS) {
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
ret = -1;
@@ -10428,10 +10560,11 @@ static int wdc_vs_temperature_stats(int argc, char **argv,
}
/* get the temperature stats or report errors */
- ret = nvme_identify_ctrl(fd, &id_ctrl);
+ ret = nvme_identify_ctrl(dev_fd(dev), &id_ctrl);
if (ret != 0)
goto out;
- ret = nvme_get_log_smart(fd, NVME_NSID_ALL, false, &smart_log);
+ ret = nvme_get_log_smart(dev_fd(dev), NVME_NSID_ALL, false,
+ &smart_log);
if (ret != 0)
goto out;
@@ -10439,14 +10572,14 @@ 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(fd, 0x10, 0, &hctm_tmt);
+ nvme_get_features_simple(dev_fd(dev), 0x10, 0, &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",
- devicename, WDC_DE_GLOBAL_NSID);
+ dev->name, WDC_DE_GLOBAL_NSID);
printf("Current Composite Temperature : %d °C\n", temperature);
printf("WCTEMP : %"PRIu16" °C\n", id_ctrl.wctemp - 273);
@@ -10493,7 +10626,7 @@ static int wdc_vs_temperature_stats(int argc, char **argv,
out:
nvme_show_status(ret);
nvme_free_tree(r);
- close(fd);
+ dev_close(dev);
return ret;
}
@@ -10501,26 +10634,27 @@ static int wdc_capabilities(int argc, char **argv,
struct command *command, struct plugin *plugin)
{
const char *desc = "Send a capabilities command.";
- nvme_root_t r;
uint64_t capabilities = 0;
- int fd;
+ struct nvme_dev *dev;
+ nvme_root_t r;
+ int ret;
OPT_ARGS(opts) =
{
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
+ if (ret)
+ return ret;
/* get capabilities */
r = nvme_scan(NULL);
- wdc_check_device(r, fd);
- capabilities = wdc_get_drive_capabilities(r, fd);
+ wdc_check_device(r, dev);
+ capabilities = wdc_get_drive_capabilities(r, dev);
/* print command and supported status */
- printf("WDC Plugin Capabilities for NVME device:%s\n", devicename);
+ printf("WDC Plugin Capabilities for NVME device:%s\n", dev->name);
printf("cap-diag : %s\n",
capabilities & WDC_DRIVE_CAP_CAP_DIAG ? "Supported" : "Not Supported");
printf("drive-log : %s\n",
@@ -10598,7 +10732,7 @@ static int wdc_capabilities(int argc, char **argv,
capabilities & WDC_DRIVE_CAP_DEVICE_WAF ? "Supported" : "Not Supported");
printf("capabilities : Supported\n");
nvme_free_tree(r);
- close(fd);
+ dev_close(dev);
return 0;
}
@@ -10606,22 +10740,23 @@ static int wdc_cloud_ssd_plugin_version(int argc, char **argv,
struct command *command, struct plugin *plugin)
{
const char *desc = "Get Cloud SSD Plugin Version command.";
- nvme_root_t r;
uint64_t capabilities = 0;
- int fd;
+ struct nvme_dev *dev;
+ nvme_root_t r;
+ int ret;
OPT_ARGS(opts) = {
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
+ if (ret)
+ return ret;
/* get capabilities */
r = nvme_scan(NULL);
- wdc_check_device(r, fd);
- capabilities = wdc_get_drive_capabilities(r, fd);
+ wdc_check_device(r, dev);
+ capabilities = wdc_get_drive_capabilities(r, dev);
if ((capabilities & WDC_DRIVE_CAP_CLOUD_SSD_VERSION) == WDC_DRIVE_CAP_CLOUD_SSD_VERSION) {
/* print command and supported status */
@@ -10631,7 +10766,7 @@ static int wdc_cloud_ssd_plugin_version(int argc, char **argv,
}
nvme_free_tree(r);
- close(fd);
+ dev_close(dev);
return 0;
}
@@ -10642,7 +10777,8 @@ static int wdc_cloud_boot_SSD_version(int argc, char **argv,
const char *namespace_id = "desired namespace id";
nvme_root_t r;
uint64_t capabilities = 0;
- int fd, ret = -1;
+ struct nvme_dev *dev;
+ int ret;
int major = 0, minor = 0;
__u8 *data = NULL;
wdc_nvme_ext_smart_log *ext_smart_log_ptr = NULL;
@@ -10660,18 +10796,19 @@ static int wdc_cloud_boot_SSD_version(int argc, char **argv,
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ ret = parse_and_open(&dev, argc, argv, desc, opts);
+ if (ret)
+ return ret;
/* get capabilities */
r = nvme_scan(NULL);
- wdc_check_device(r, fd);
- capabilities = wdc_get_drive_capabilities(r, fd);
+ wdc_check_device(r, dev);
+ capabilities = wdc_get_drive_capabilities(r, dev);
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(fd, &data, 0, cfg.namespace_id);
+ ret = nvme_get_ext_smart_cloud_log(dev_fd(dev), &data, 0,
+ cfg.namespace_id);
ext_smart_log_ptr = (wdc_nvme_ext_smart_log *)data;
if (ret == 0) {
@@ -10693,7 +10830,7 @@ static int wdc_cloud_boot_SSD_version(int argc, char **argv,
}
nvme_free_tree(r);
- close(fd);
+ dev_close(dev);
return ret;
}
@@ -10704,9 +10841,9 @@ static int wdc_enc_get_log(int argc, char **argv, struct command *command,
char *file = "Output file pathname.";
char *size = "Data retrieval transfer size.";
char *log = "Enclosure Log Page ID.";
+ struct nvme_dev *dev;
FILE *output_fd;
int xfer_size = 0;
- int fd;
int len;
int err = 0;
@@ -10729,12 +10866,11 @@ static int wdc_enc_get_log(int argc, char **argv, struct command *command,
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0) {
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
- }
- if (!wdc_enc_check_model(fd)) {
+ if (!wdc_enc_check_model(dev)) {
err = -EINVAL;
goto closed_fd;
}
@@ -10770,10 +10906,15 @@ static int wdc_enc_get_log(int argc, char **argv, struct command *command,
if (cfg.log_id == WDC_ENC_NIC_CRASH_DUMP_ID_SLOT_1 || cfg.log_id == WDC_ENC_NIC_CRASH_DUMP_ID_SLOT_2
|| cfg.log_id == WDC_ENC_NIC_CRASH_DUMP_ID_SLOT_3 || 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(fd, cfg.log_id, xfer_size, WDC_NVME_ENC_NIC_LOG_SIZE, output_fd);
+ err = wdc_enc_get_nic_log(dev, 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(fd, NULL, 0, xfer_size, output_fd, cfg.log_id, 0, 0);
+ err = wdc_enc_submit_move_data(dev, NULL, 0,
+ xfer_size, output_fd,
+ cfg.log_id, 0, 0);
}
if (err == WDC_RESULT_NOT_AVAILABLE) {
@@ -10784,12 +10925,14 @@ static int wdc_enc_get_log(int argc, char **argv, struct command *command,
}
}
closed_fd:
- close(fd);
+ dev_close(dev);
ret:
return err;
}
-static int wdc_enc_submit_move_data(int fd, char *cmd, int len, int xfer_size, FILE *out, int log_id, int cdw14, int cdw15)
+static int wdc_enc_submit_move_data(struct nvme_dev *dev, char *cmd, int len,
+ int xfer_size, FILE *out, int log_id,
+ int cdw14, int cdw15)
{
struct timespec time;
uint32_t response_size, more;
@@ -10840,8 +10983,8 @@ static int wdc_enc_submit_move_data(int fd, char *cmd, int len, int xfer_size, F
d);
#endif
nvme_cmd.result = 0;
- err = nvme_submit_admin_passthru(fd, &nvme_cmd, NULL);
- if (err == NVME_SC_INTERNAL) {
+ err = nvme_submit_admin_passthru(dev_fd(dev), &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);
}
@@ -10868,7 +11011,8 @@ static int wdc_enc_submit_move_data(int fd, char *cmd, int len, int xfer_size, F
nvme_cmd.cdw14 = cdw14;
nvme_cmd.cdw15 = cdw15;
nvme_cmd.result = 0; /* returned result !=0 indicates more data available */
- err = nvme_submit_admin_passthru(fd, &nvme_cmd, NULL);
+ err = nvme_submit_admin_passthru(dev_fd(dev),
+ &nvme_cmd, NULL);
if (err != 0) {
more = 0;
fprintf(stderr, "%s: ERROR : WDC : NVMe Rcv Mgmt ", __func__);
@@ -10890,7 +11034,7 @@ static int wdc_enc_submit_move_data(int fd, char *cmd, int len, int xfer_size, F
return err;
}
-static int wdc_enc_get_nic_log(int fd, __u8 log_id, __u32 xfer_size, __u32 data_len, FILE *out)
+static int wdc_enc_get_nic_log(struct nvme_dev *dev, __u8 log_id, __u32 xfer_size, __u32 data_len, FILE *out)
{
__u8 *dump_data;
__u32 curr_data_offset, curr_data_len;
@@ -10925,7 +11069,8 @@ static int wdc_enc_get_nic_log(int fd, __u8 log_id, __u32 xfer_size, __u32 data_
#ifdef WDC_NVME_CLI_DEBUG
fprintf(stderr, "nsid 0x%08x addr 0x%08llx, data_len 0x%08x, cdw10 0x%08x, cdw11 0x%08x, cdw12 0x%08x, cdw13 0x%08x, cdw14 0x%08x \n", 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(fd, &admin_cmd, NULL);
+ ret = nvme_submit_admin_passthru(dev_fd(dev), &admin_cmd,
+ NULL);
if (ret != 0) {
nvme_show_status(ret);
fprintf(stderr, "%s: ERROR : WDC : Get chunk %d, size = 0x%x, offset = 0x%x, addr = 0x%lx\n",
diff --git a/plugins/wdc/wdc-nvme.h b/plugins/wdc/wdc-nvme.h
index c7b7f4c..242cf9a 100644
--- a/plugins/wdc/wdc-nvme.h
+++ b/plugins/wdc/wdc-nvme.h
@@ -5,7 +5,7 @@
#if !defined(WDC_NVME) || defined(CMD_HEADER_MULTI_READ)
#define WDC_NVME
-#define WDC_PLUGIN_VERSION "2.0.3"
+#define WDC_PLUGIN_VERSION "2.1.2"
#include "cmd.h"
PLUGIN(NAME("wdc", "Western Digital vendor specific extensions", WDC_PLUGIN_VERSION),
diff --git a/plugins/ymtc/ymtc-nvme.c b/plugins/ymtc/ymtc-nvme.c
index cfbf6a6..d04481c 100644
--- a/plugins/ymtc/ymtc-nvme.c
+++ b/plugins/ymtc/ymtc-nvme.c
@@ -21,8 +21,8 @@ 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(int fd, __u32 nsid, const char *devname,
- struct nvme_ymtc_smart_log *smart)
+static int show_ymtc_smart_log(struct nvme_dev *dev, __u32 nsid,
+ struct nvme_ymtc_smart_log *smart)
{
struct nvme_id_ctrl ctrl;
char fw_ver[10];
@@ -40,7 +40,7 @@ static int show_ymtc_smart_log(int fd, __u32 nsid, const char *devname,
free(nm);
return -1;
}
- err = nvme_identify_ctrl(fd, &ctrl);
+ err = nvme_identify_ctrl(dev_fd(dev), &ctrl);
if (err) {
free(nm);
free(raw);
@@ -52,7 +52,8 @@ static int show_ymtc_smart_log(int fd, __u32 nsid, const char *devname,
ctrl.fr[4], ctrl.fr[5], ctrl.fr[6]);
/* Table Title */
- printf("Additional Smart Log for NVME device:%s namespace-id:%x\n", devname, nsid);
+ printf("Additional Smart Log for NVME device:%s namespace-id:%x\n",
+ dev->name, nsid);
/* Clumn Name*/
printf("key normalized raw\n");
/* 00 SI_VD_PROGRAM_FAIL */
@@ -119,15 +120,16 @@ static int show_ymtc_smart_log(int fd, __u32 nsid, const char *devname,
static int get_additional_smart_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
{
struct nvme_ymtc_smart_log smart_log;
- int err, fd;
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;
struct config {
__u32 namespace_id;
bool raw_binary;
};
+ int err;
struct config cfg = {
.namespace_id = NVME_NSID_ALL,
@@ -139,21 +141,21 @@ static int get_additional_smart_log(int argc, char **argv, struct command *cmd,
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
- return fd;
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
+ return err;
- err = nvme_get_nsid_log(fd, false, 0xca, cfg.namespace_id,
+ err = nvme_get_nsid_log(dev_fd(dev), false, 0xca, cfg.namespace_id,
sizeof(smart_log), &smart_log);
if (!err) {
if (!cfg.raw_binary)
- err = show_ymtc_smart_log(fd, cfg.namespace_id, devicename, &smart_log);
+ err = show_ymtc_smart_log(dev, cfg.namespace_id, &smart_log);
else
d_raw((unsigned char *)&smart_log, sizeof(smart_log));
}
if (err > 0)
nvme_show_status(err);
- close(fd);
+ dev_close(dev);
return err;
}
diff --git a/plugins/zns/zns.c b/plugins/zns/zns.c
index 0b96346..f8809ba 100644
--- a/plugins/zns/zns.c
+++ b/plugins/zns/zns.c
@@ -120,7 +120,8 @@ static int id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *pl
enum nvme_print_flags flags;
struct nvme_zns_id_ctrl ctrl;
- int fd, err = -1;
+ struct nvme_dev *dev;
+ int err = -1;
struct config {
char *output_format;
@@ -135,15 +136,15 @@ static int id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *pl
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
return errno;
err = flags = validate_output_format(cfg.output_format);
if (flags < 0)
goto close_fd;
- err = nvme_zns_identify_ctrl(fd, &ctrl);
+ err = nvme_zns_identify_ctrl(dev_fd(dev), &ctrl);
if (!err)
nvme_show_zns_id_ctrl(&ctrl, flags);
else if (err > 0)
@@ -151,7 +152,7 @@ static int id_ctrl(int argc, char **argv, struct command *cmd, struct plugin *pl
else
perror("zns identify controller");
close_fd:
- close(fd);
+ dev_close(dev);
return err;
}
@@ -166,7 +167,8 @@ static int id_ns(int argc, char **argv, struct command *cmd, struct plugin *plug
enum nvme_print_flags flags;
struct nvme_zns_id_ns ns;
struct nvme_id_ns id_ns;
- int fd, err = -1;
+ struct nvme_dev *dev;
+ int err = -1;
struct config {
char *output_format;
@@ -187,8 +189,8 @@ static int id_ns(int argc, char **argv, struct command *cmd, struct plugin *plug
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
return errno;
flags = validate_output_format(cfg.output_format);
@@ -200,20 +202,20 @@ static int id_ns(int argc, char **argv, struct command *cmd, struct plugin *plug
flags |= VERBOSE;
if (!cfg.namespace_id) {
- err = nvme_get_nsid(fd, &cfg.namespace_id);
+ err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
perror("get-namespace-id");
goto close_fd;
}
}
- err = nvme_identify_ns(fd, cfg.namespace_id, &id_ns);
+ err = nvme_identify_ns(dev_fd(dev), cfg.namespace_id, &id_ns);
if (err) {
nvme_show_status(err);
goto close_fd;
}
- err = nvme_zns_identify_ns(fd, cfg.namespace_id, &ns);
+ err = nvme_zns_identify_ns(dev_fd(dev), cfg.namespace_id, &ns);
if (!err)
nvme_show_zns_id_ns(&ns, &id_ns, flags);
else if (err > 0)
@@ -221,7 +223,7 @@ static int id_ns(int argc, char **argv, struct command *cmd, struct plugin *plug
else
perror("zns identify namespace");
close_fd:
- close(fd);
+ dev_close(dev);
return err;
}
@@ -231,8 +233,8 @@ static int zns_mgmt_send(int argc, char **argv, struct command *cmd, struct plug
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";
-
- int err, fd, zcapc = 0;
+ struct nvme_dev *dev;
+ int err, zcapc = 0;
char *command;
__u32 result;
@@ -253,16 +255,16 @@ static int zns_mgmt_send(int argc, char **argv, struct command *cmd, struct plug
OPT_END()
};
- err = fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
goto ret;
err = asprintf(&command, "%s-%s", plugin->name, cmd->name);
if (err < 0)
- goto close_fd;
+ goto close_dev;
if (!cfg.namespace_id) {
- err = nvme_get_nsid(fd, &cfg.namespace_id);
+ err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
perror("get-namespace-id");
goto free;
@@ -271,7 +273,7 @@ static int zns_mgmt_send(int argc, char **argv, struct command *cmd, struct plug
struct nvme_zns_mgmt_send_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.nsid = cfg.namespace_id,
.slba = cfg.zslba,
.zsa = zsa,
@@ -297,8 +299,8 @@ static int zns_mgmt_send(int argc, char **argv, struct command *cmd, struct plug
perror(desc);
free:
free(command);
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
ret:
return err;
}
@@ -344,7 +346,8 @@ 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";
- int fd, ffd = STDIN_FILENO, err = -1;
+ int ffd = STDIN_FILENO, err = -1;
+ struct nvme_dev *dev;
void *buf = NULL;
struct config {
@@ -372,41 +375,42 @@ static int zone_mgmt_send(int argc, char **argv, struct command *cmd, struct plu
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
return errno;
if (!cfg.namespace_id) {
- err = nvme_get_nsid(fd, &cfg.namespace_id);
+ err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
perror("get-namespace-id");
- goto close_fd;
+ goto close_dev;
}
}
if (!cfg.zsa) {
fprintf(stderr, "zone send action must be specified\n");
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
if (cfg.zsa == NVME_ZNS_ZSA_SET_DESC_EXT) {
if(!cfg.data_len) {
- int data_len = get_zdes_bytes(fd, cfg.namespace_id);
+ int data_len = get_zdes_bytes(dev_fd(dev),
+ cfg.namespace_id);
if (data_len == 0) {
fprintf(stderr,
"Zone Descriptor Extensions are not supported\n");
- goto close_fd;
+ goto close_dev;
} else if (data_len < 0) {
err = data_len;
- goto close_fd;
+ goto close_dev;
}
cfg.data_len = data_len;
}
if (posix_memalign(&buf, getpagesize(), cfg.data_len)) {
fprintf(stderr, "can not allocate feature payload\n");
- goto close_fd;
+ goto close_dev;
}
memset(buf, 0, cfg.data_len);
@@ -428,13 +432,13 @@ static int zone_mgmt_send(int argc, char **argv, struct command *cmd, struct plu
fprintf(stderr,
"data, data_len only valid with set extended descriptor\n");
err = -EINVAL;
- goto close_fd;
+ goto close_dev;
}
}
struct nvme_zns_mgmt_send_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.nsid = cfg.namespace_id,
.slba = cfg.zslba,
.zsa = cfg.zsa,
@@ -461,8 +465,8 @@ close_ffd:
close(ffd);
free:
free(buf);
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
return err;
}
@@ -487,8 +491,8 @@ static int open_zone(int argc, char **argv, struct command *cmd, struct plugin *
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";
-
- int err, fd;
+ struct nvme_dev *dev;
+ int err;
struct config {
__u64 zslba;
@@ -510,21 +514,21 @@ static int open_zone(int argc, char **argv, struct command *cmd, struct plugin *
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
return errno;
if (!cfg.namespace_id) {
- err = nvme_get_nsid(fd, &cfg.namespace_id);
+ err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
perror("get-namespace-id");
- goto close_fd;
+ goto close_dev;
}
}
struct nvme_zns_mgmt_send_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.nsid = cfg.namespace_id,
.slba = cfg.zslba,
.zsa = NVME_ZNS_ZSA_OPEN,
@@ -541,8 +545,8 @@ static int open_zone(int argc, char **argv, struct command *cmd, struct plugin *
(uint64_t)cfg.zslba, cfg.namespace_id);
else
nvme_show_status(err);
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
return err;
}
@@ -568,7 +572,8 @@ static int set_zone_desc(int argc, char **argv, struct command *cmd, struct plug
const char *data = "optional file for zone extention data (default stdin)";
const char *timeout = "timeout value, in milliseconds";
- int fd, ffd = STDIN_FILENO, err;
+ int ffd = STDIN_FILENO, err;
+ struct nvme_dev *dev;
void *buf = NULL;
int data_len;
@@ -591,33 +596,33 @@ static int set_zone_desc(int argc, char **argv, struct command *cmd, struct plug
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
return errno;
if (!cfg.namespace_id) {
- err = nvme_get_nsid(fd, &cfg.namespace_id);
+ err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
perror("get-namespace-id");
- goto close_fd;
+ goto close_dev;
}
}
- data_len = get_zdes_bytes(fd, cfg.namespace_id);
+ data_len = get_zdes_bytes(dev_fd(dev), cfg.namespace_id);
if (!data_len || data_len < 0) {
fprintf(stderr,
"zone format does not provide descriptor extention\n");
errno = EINVAL;
err = -1;
- goto close_fd;
+ goto close_dev;
}
buf = calloc(1, data_len);
if (!buf) {
perror("could not alloc memory for zone desc");
err = -ENOMEM;
- goto close_fd;
+ goto close_dev;
}
if (cfg.file) {
@@ -637,7 +642,7 @@ static int set_zone_desc(int argc, char **argv, struct command *cmd, struct plug
struct nvme_zns_mgmt_send_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.nsid = cfg.namespace_id,
.slba = cfg.zslba,
.zsa = NVME_ZNS_ZSA_SET_DESC_EXT,
@@ -661,8 +666,8 @@ close_ffd:
close(ffd);
free:
free(buf);
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
return err;
}
@@ -672,8 +677,8 @@ static int zrwa_flush_zone(int argc, char **argv, struct command *cmd, struct pl
const char *desc = "Flush Explicit ZRWA Range";
const char *slba = "LBA to flush up to";
const char *timeout = "timeout value, in milliseconds";
-
- int err, fd;
+ struct nvme_dev *dev;
+ int err;
struct config {
__u64 lba;
@@ -690,21 +695,21 @@ static int zrwa_flush_zone(int argc, char **argv, struct command *cmd, struct pl
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
return errno;
if (!cfg.namespace_id) {
- err = nvme_get_nsid(fd, &cfg.namespace_id);
+ err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
perror("get-namespace-id");
- goto close_fd;
+ goto close_dev;
}
}
struct nvme_zns_mgmt_send_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.nsid = cfg.namespace_id,
.slba = cfg.lba,
.zsa = NVME_ZNS_ZSA_ZRWA_FLUSH,
@@ -721,8 +726,8 @@ static int zrwa_flush_zone(int argc, char **argv, struct command *cmd, struct pl
(uint64_t)cfg.lba, cfg.namespace_id);
else
nvme_show_status(err);
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
return err;
}
@@ -736,8 +741,9 @@ static int zone_mgmt_recv(int argc, char **argv, struct command *cmd, struct plu
const char *data_len = "length of data in bytes";
enum nvme_print_flags flags;
- int fd, err = -1;
+ struct nvme_dev *dev;
void *data = NULL;
+ int err = -1;
struct config {
char *output_format;
@@ -764,39 +770,39 @@ static int zone_mgmt_recv(int argc, char **argv, struct command *cmd, struct plu
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
return errno;
flags = validate_output_format(cfg.output_format);
if (flags < 0)
- goto close_fd;
+ goto close_dev;
if (!cfg.namespace_id) {
- err = nvme_get_nsid(fd, &cfg.namespace_id);
+ err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
perror("get-namespace-id");
- goto close_fd;
+ goto close_dev;
}
}
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_fd;
+ goto close_dev;
}
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_fd;
+ goto close_dev;
}
}
struct nvme_zns_mgmt_recv_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.nsid = cfg.namespace_id,
.slba = cfg.zslba,
.zra = cfg.zra,
@@ -817,8 +823,8 @@ static int zone_mgmt_recv(int argc, char **argv, struct command *cmd, struct plu
perror("zns zone-mgmt-recv");
free(data);
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
return err;
}
@@ -833,11 +839,11 @@ static int report_zones(int argc, char **argv, struct command *cmd, struct plugi
const char *verbose = "show report zones verbosity";
enum nvme_print_flags flags;
- int fd, zdes = 0, err = -1;
+ int zdes = 0, err = -1;
+ struct nvme_dev *dev;
__u32 report_size;
- void *report;
bool huge = false;
- struct nvme_zone_report *buff;
+ struct nvme_zone_report *report, *buff;
unsigned int nr_zones_chunks = 1024, /* 1024 entries * 64 bytes per entry = 64k byte transfer */
nr_zones_retrieved = 0,
@@ -879,39 +885,39 @@ static int report_zones(int argc, char **argv, struct command *cmd, struct plugi
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
return errno;
flags = validate_output_format(cfg.output_format);
if (flags < 0)
- goto close_fd;
+ goto close_dev;
if (cfg.verbose)
flags |= VERBOSE;
if (!cfg.namespace_id) {
- err = nvme_get_nsid(fd, &cfg.namespace_id);
+ err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
perror("get-namespace-id");
- goto close_fd;
+ goto close_dev;
}
}
if (cfg.extended) {
- zdes = get_zdes_bytes(fd, cfg.namespace_id);
+ zdes = get_zdes_bytes(dev_fd(dev), cfg.namespace_id);
if (zdes < 0) {
err = zdes;
- goto close_fd;
+ goto close_dev;
}
}
- err = nvme_identify_ns(fd, cfg.namespace_id, &id_ns);
+ err = nvme_identify_ns(dev_fd(dev), cfg.namespace_id, &id_ns);
if (err) {
nvme_show_status(err);
- goto close_fd;
+ goto close_dev;
}
- err = nvme_zns_identify_ns(fd, cfg.namespace_id, &id_zns);
+ err = nvme_zns_identify_ns(dev_fd(dev), 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);
@@ -919,17 +925,17 @@ static int report_zones(int argc, char **argv, struct command *cmd, struct plugi
}
else {
nvme_show_status(err);
- goto close_fd;
+ goto close_dev;
}
log_len = sizeof(struct nvme_zone_report);
buff = calloc(1, log_len);
if (!buff) {
err = -ENOMEM;
- goto close_fd;
+ goto close_dev;
}
- err = nvme_zns_report_zones(fd, cfg.namespace_id, 0,
+ err = nvme_zns_report_zones(dev_fd(dev), cfg.namespace_id, 0,
cfg.state, false, false,
log_len, buff,
NVME_DEFAULT_IOCTL_TIMEOUT, NULL);
@@ -959,7 +965,7 @@ static int report_zones(int argc, char **argv, struct command *cmd, struct plugi
if (!report) {
perror("alloc");
err = -ENOMEM;
- goto close_fd;
+ goto close_dev;
}
offset = cfg.zslba;
@@ -977,7 +983,8 @@ 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(fd, cfg.namespace_id, offset,
+ 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);
@@ -991,7 +998,7 @@ static int report_zones(int argc, char **argv, struct command *cmd, struct plugi
zdes, log_len, flags, zone_list);
nr_zones_retrieved += nr_zones_chunks;
- offset = (nr_zones_retrieved * zsze);
+ offset = le64_to_cpu(report->entries[nr_zones_chunks-1].zslba) + zsze;
}
if (flags & JSON)
@@ -1001,8 +1008,8 @@ static int report_zones(int argc, char **argv, struct command *cmd, struct plugi
free_buff:
free(buff);
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
return err;
}
@@ -1025,10 +1032,11 @@ static int zone_append(int argc, char **argv, struct command *cmd, struct plugin
const char *data_size = "size of data in bytes";
const char *latency = "output latency statistics";
- int err = -1, fd, dfd = STDIN_FILENO, mfd = STDIN_FILENO;
+ int err = -1, dfd = STDIN_FILENO, mfd = STDIN_FILENO;
unsigned int lba_size, meta_size;
void *buf = NULL, *mbuf = NULL;
__u16 nblocks, control = 0;
+ struct nvme_dev *dev;
__u64 result;
__u8 lba_index;
struct timeval start_time, end_time;
@@ -1072,28 +1080,28 @@ static int zone_append(int argc, char **argv, struct command *cmd, struct plugin
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
return errno;
if (!cfg.data_size) {
fprintf(stderr, "Append size not provided\n");
errno = EINVAL;
- goto close_fd;
+ goto close_dev;
}
if (!cfg.namespace_id) {
- err = nvme_get_nsid(fd, &cfg.namespace_id);
+ err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
perror("get-namespace-id");
- goto close_fd;
+ goto close_dev;
}
}
- err = nvme_identify_ns(fd, cfg.namespace_id, &ns);
+ err = nvme_identify_ns(dev_fd(dev), cfg.namespace_id, &ns);
if (err) {
nvme_show_status(err);
- goto close_fd;
+ goto close_dev;
}
nvme_id_ns_flbas_to_lbaf_inuse(ns.flbas, &lba_index);
@@ -1103,7 +1111,7 @@ static int zone_append(int argc, char **argv, struct command *cmd, struct plugin
"Data size:%#"PRIx64" not aligned to lba size:%#x\n",
(uint64_t)cfg.data_size, lba_size);
errno = EINVAL;
- goto close_fd;
+ goto close_dev;
}
meta_size = ns.lbaf[lba_index].ms;
@@ -1113,20 +1121,20 @@ static int zone_append(int argc, char **argv, struct command *cmd, struct plugin
"Metadata size:%#"PRIx64" not aligned to metadata size:%#x\n",
(uint64_t)cfg.metadata_size, meta_size);
errno = EINVAL;
- goto close_fd;
+ goto close_dev;
}
if (cfg.prinfo > 0xf) {
fprintf(stderr, "Invalid value for prinfo:%#x\n", cfg.prinfo);
errno = EINVAL;
- goto close_fd;
+ goto close_dev;
}
if (cfg.data) {
dfd = open(cfg.data, O_RDONLY);
if (dfd < 0) {
perror(cfg.data);
- goto close_fd;
+ goto close_dev;
}
}
@@ -1179,7 +1187,7 @@ static int zone_append(int argc, char **argv, struct command *cmd, struct plugin
struct nvme_zns_append_args args = {
.args_size = sizeof(args),
- .fd = fd,
+ .fd = dev_fd(dev),
.nsid = cfg.namespace_id,
.zslba = cfg.zslba,
.nlb = nblocks,
@@ -1219,8 +1227,8 @@ free_data:
close_dfd:
if (cfg.data)
close(dfd);
-close_fd:
- close(fd);
+close_dev:
+ dev_close(dev);
return err;
}
@@ -1231,7 +1239,8 @@ static int changed_zone_list(int argc, char **argv, struct command *cmd, struct
struct nvme_zns_changed_zone_log log;
enum nvme_print_flags flags;
- int fd, err = -1;
+ struct nvme_dev *dev;
+ int err = -1;
struct config {
char *output_format;
@@ -1250,8 +1259,8 @@ static int changed_zone_list(int argc, char **argv, struct command *cmd, struct
OPT_END()
};
- fd = parse_and_open(argc, argv, desc, opts);
- if (fd < 0)
+ err = parse_and_open(&dev, argc, argv, desc, opts);
+ if (err)
return errno;
flags = validate_output_format(cfg.output_format);
@@ -1259,14 +1268,15 @@ static int changed_zone_list(int argc, char **argv, struct command *cmd, struct
goto close_fd;
if (!cfg.namespace_id) {
- err = nvme_get_nsid(fd, &cfg.namespace_id);
+ err = nvme_get_nsid(dev_fd(dev), &cfg.namespace_id);
if (err < 0) {
perror("get-namespace-id");
goto close_fd;
}
}
- err = nvme_get_log_zns_changed_zones(fd, cfg.namespace_id, cfg.rae, &log);
+ err = nvme_get_log_zns_changed_zones(dev_fd(dev), cfg.namespace_id,
+ cfg.rae, &log);
if (!err)
nvme_show_zns_changed(&log, flags);
else if (err > 0)
@@ -1275,6 +1285,6 @@ static int changed_zone_list(int argc, char **argv, struct command *cmd, struct
perror("zns changed-zone-list");
close_fd:
- close(fd);
+ dev_close(dev);
return err;
}