Adding upstream version 1.15.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
2066c5b305
commit
90b6101daf
116 changed files with 6031 additions and 2284 deletions
|
@ -6,7 +6,7 @@
|
|||
|
||||
#include "cmd.h"
|
||||
|
||||
PLUGIN(NAME("amzn", "Amazon vendor specific extensions"),
|
||||
PLUGIN(NAME("amzn", "Amazon vendor specific extensions", NVME_VERSION),
|
||||
COMMAND_LIST(
|
||||
ENTRY("id-ctrl", "Send NVMe Identify Controller", id_ctrl)
|
||||
)
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#include "cmd.h"
|
||||
|
||||
PLUGIN(NAME("dera", "Dera vendor specific extensions"),
|
||||
PLUGIN(NAME("dera", "Dera vendor specific extensions", NVME_VERSION),
|
||||
COMMAND_LIST(
|
||||
ENTRY("smart-log-add", "Retrieve Dera SMART Log, show it", get_status, "stat")
|
||||
)
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#include "cmd.h"
|
||||
|
||||
PLUGIN(NAME("huawei", "Huawei vendor specific extensions"),
|
||||
PLUGIN(NAME("huawei", "Huawei vendor specific extensions", NVME_VERSION),
|
||||
COMMAND_LIST(
|
||||
ENTRY("list", "List all Huawei NVMe devices and namespaces on machine", huawei_list)
|
||||
ENTRY("id-ctrl", "Huawei identify controller", huawei_id_ctrl)
|
||||
|
|
|
@ -454,7 +454,7 @@ static int get_temp_stats_log(int argc, char **argv, struct command *cmd, struct
|
|||
struct intel_temp_stats stats;
|
||||
int err, fd;
|
||||
|
||||
const char *desc = "Get Intel Marketing Name log and show it.";
|
||||
const char *desc = "Get Temperature Statistics log and show it.";
|
||||
const char *raw = "dump output in binary format";
|
||||
struct config {
|
||||
int raw_binary;
|
||||
|
@ -1065,7 +1065,7 @@ static int get_lat_stats_log(int argc, char **argv, struct command *cmd, struct
|
|||
__u32 thresholds[OPTANE_V1000_BUCKET_LEN] = {0};
|
||||
__u32 result;
|
||||
|
||||
err = nvme_get_feature(fd, 0, 0xf7, 0, cfg.write ? 0x1 : 0x0,
|
||||
err = nvme_get_feature(fd, 0, 0xf7, 0, cfg.write ? 0x1 : 0x0, 0,
|
||||
sizeof(thresholds), thresholds, &result);
|
||||
if (err) {
|
||||
fprintf(stderr, "Quering thresholds failed. NVMe Status:%s(%x)\n",
|
||||
|
@ -1542,7 +1542,7 @@ static int enable_lat_stats_tracking(int argc, char **argv,
|
|||
return fd;
|
||||
switch (option) {
|
||||
case None:
|
||||
err = nvme_get_feature(fd, nsid, fid, sel, cdw11, data_len, buf,
|
||||
err = nvme_get_feature(fd, nsid, fid, sel, cdw11, 0, data_len, buf,
|
||||
&result);
|
||||
if (!err) {
|
||||
printf(
|
||||
|
@ -1555,7 +1555,7 @@ static int enable_lat_stats_tracking(int argc, char **argv,
|
|||
break;
|
||||
case True:
|
||||
case False:
|
||||
err = nvme_set_feature(fd, nsid, fid, option, cdw12, save,
|
||||
err = nvme_set_feature(fd, nsid, fid, option, cdw12, save, 0,
|
||||
data_len, buf, &result);
|
||||
if (err > 0) {
|
||||
fprintf(stderr, "NVMe Status:%s(%x)\n",
|
||||
|
@ -1636,7 +1636,7 @@ static int set_lat_stats_thresholds(int argc, char **argv,
|
|||
}
|
||||
|
||||
err = nvme_set_feature(fd, nsid, fid, cfg.write ? 0x1 : 0x0,
|
||||
cdw12, save, OPTANE_V1000_BUCKET_LEN,
|
||||
cdw12, save, 0, OPTANE_V1000_BUCKET_LEN,
|
||||
thresholds, &result);
|
||||
|
||||
if (err > 0) {
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#include "cmd.h"
|
||||
|
||||
PLUGIN(NAME("intel", "Intel vendor specific extensions"),
|
||||
PLUGIN(NAME("intel", "Intel vendor specific extensions", NVME_VERSION),
|
||||
COMMAND_LIST(
|
||||
ENTRY("id-ctrl", "Send NVMe Identify Controller", id_ctrl)
|
||||
ENTRY("internal-log", "Retrieve Intel internal firmware log, save it", get_internal_log)
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
#include "cmd.h"
|
||||
|
||||
PLUGIN(NAME("lnvm", "LightNVM specific extensions"),
|
||||
PLUGIN(NAME("lnvm", "LightNVM specific extensions", NVME_VERSION),
|
||||
COMMAND_LIST(
|
||||
ENTRY("list", "List available LightNVM devices", lnvm_list)
|
||||
ENTRY("info", "List general information and available target engines", lnvm_info)
|
||||
|
|
|
@ -503,7 +503,7 @@ static int mb_get_powermanager_status(int argc, char **argv, struct command *cmd
|
|||
fd = parse_and_open(argc, argv, desc, opts);
|
||||
if (fd < 0) return fd;
|
||||
|
||||
err = nvme_get_feature(fd, 0, feature_id, 0, 0, 0, NULL, &result);
|
||||
err = nvme_get_feature(fd, 0, feature_id, 0, 0, 0, 0, NULL, &result);
|
||||
if (err < 0) {
|
||||
perror("get-feature");
|
||||
}
|
||||
|
@ -545,7 +545,7 @@ static int mb_set_powermanager_status(int argc, char **argv, struct command *cmd
|
|||
fd = parse_and_open(argc, argv, desc, opts);
|
||||
if (fd < 0) return fd;
|
||||
|
||||
err = nvme_set_feature(fd, 0, cfg.feature_id, cfg.value, 0, cfg.save, 0, NULL, &result);
|
||||
err = nvme_set_feature(fd, 0, cfg.feature_id, cfg.value, 0, cfg.save, 0, 0, NULL, &result);
|
||||
if (err < 0) {
|
||||
perror("set-feature");
|
||||
}
|
||||
|
@ -602,7 +602,7 @@ static int mb_set_high_latency_log(int argc, char **argv, struct command *cmd, s
|
|||
}
|
||||
cfg.value = (param1 << MB_FEAT_HIGH_LATENCY_VALUE_SHIFT) | param2;
|
||||
|
||||
err = nvme_set_feature(fd, 0, cfg.feature_id, cfg.value, 0, 0, 0, NULL, &result);
|
||||
err = nvme_set_feature(fd, 0, cfg.feature_id, cfg.value, 0, 0, 0, 0, NULL, &result);
|
||||
if (err < 0) {
|
||||
perror("set-feature");
|
||||
}
|
||||
|
@ -1038,7 +1038,7 @@ static int memblaze_clear_error_log(int argc, char **argv, struct command *cmd,
|
|||
|
||||
|
||||
|
||||
err = nvme_set_feature(fd, 0, cfg.feature_id, cfg.value, 0, cfg.save, 0, NULL, &result);
|
||||
err = nvme_set_feature(fd, 0, cfg.feature_id, cfg.value, 0, cfg.save, 0, 0, NULL, &result);
|
||||
if (err < 0) {
|
||||
perror("set-feature");
|
||||
}
|
||||
|
@ -1115,7 +1115,7 @@ static int mb_set_lat_stats(int argc, char **argv,
|
|||
return fd;
|
||||
switch (option) {
|
||||
case None:
|
||||
err = nvme_get_feature(fd, nsid, fid, sel, cdw11, data_len, buf,
|
||||
err = nvme_get_feature(fd, nsid, fid, sel, cdw11, 0, data_len, buf,
|
||||
&result);
|
||||
if (!err) {
|
||||
printf(
|
||||
|
@ -1128,7 +1128,7 @@ static int mb_set_lat_stats(int argc, char **argv,
|
|||
break;
|
||||
case True:
|
||||
case False:
|
||||
err = nvme_set_feature(fd, nsid, fid, option, cdw12, save,
|
||||
err = nvme_set_feature(fd, nsid, fid, option, cdw12, save, 0,
|
||||
data_len, buf, &result);
|
||||
if (err > 0) {
|
||||
fprintf(stderr, "NVMe Status:%s(%x)\n",
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
PLUGIN(NAME("memblaze", "Memblaze vendor specific extensions"),
|
||||
PLUGIN(NAME("memblaze", "Memblaze vendor specific extensions", NVME_VERSION),
|
||||
COMMAND_LIST(
|
||||
ENTRY("smart-log-add", "Retrieve Memblaze SMART Log, show it", mb_get_additional_smart_log)
|
||||
ENTRY("get-pm-status", "Get Memblaze Power Manager Status", mb_get_powermanager_status)
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <sys/stat.h>
|
||||
#include "nvme.h"
|
||||
#include "nvme-print.h"
|
||||
#include "nvme-status.h"
|
||||
#include "nvme-ioctl.h"
|
||||
#include <sys/ioctl.h>
|
||||
#include <limits.h>
|
||||
|
@ -38,7 +39,7 @@
|
|||
/* Plugin version major_number.minor_number.patch */
|
||||
static const char *__version_major = "1";
|
||||
static const char *__version_minor = "0";
|
||||
static const char *__version_patch = "5";
|
||||
static const char *__version_patch = "6";
|
||||
|
||||
/* supported models of micron plugin; new models should be added at the end
|
||||
* before UNKNOWN_MODEL. Make sure M5410 is first in the list !
|
||||
|
@ -626,7 +627,7 @@ static int micron_smbus_option(int argc, char **argv,
|
|||
|
||||
if (!strcmp(opt.option, "enable")) {
|
||||
cdw11 = opt.value << 1 | 1;
|
||||
err = nvme_set_feature(fd, 1, fid, cdw11, 0, opt.save, 0, 0, &result);
|
||||
err = nvme_set_feature(fd, 1, fid, cdw11, 0, opt.save, 0, 0, 0, &result);
|
||||
if (err == 0) {
|
||||
printf("successfully enabled SMBus on drive\n");
|
||||
} else {
|
||||
|
@ -635,7 +636,7 @@ static int micron_smbus_option(int argc, char **argv,
|
|||
}
|
||||
else if (!strcmp(opt.option, "status")) {
|
||||
cdw10 = opt.value;
|
||||
err = nvme_get_feature(fd, 1, fid, cdw10, 0, 0, 0, &result);
|
||||
err = nvme_get_feature(fd, 1, fid, cdw10, 0, 0, 0, 0, &result);
|
||||
if (err == 0) {
|
||||
printf("SMBus status on the drive: %s (returns %s temperature) \n",
|
||||
(result & 1) ? "enabled" : "disabled",
|
||||
|
@ -646,7 +647,7 @@ static int micron_smbus_option(int argc, char **argv,
|
|||
}
|
||||
else if (!strcmp(opt.option, "disable")) {
|
||||
cdw11 = opt.value << 1 | 0;
|
||||
err = nvme_set_feature(fd, 1, fid, cdw11, 0, opt.save, 0, 0, &result);
|
||||
err = nvme_set_feature(fd, 1, fid, cdw11, 0, opt.save, 0, 0, 0, &result);
|
||||
if (err == 0) {
|
||||
printf("Successfully disabled SMBus on drive\n");
|
||||
} else {
|
||||
|
@ -932,9 +933,11 @@ static int micron_clear_pcie_correctable_errors(int argc, char **argv,
|
|||
|
||||
/* For M51CX models, PCIe errors are cleared using 0xC3 feature */
|
||||
if (model == M51CX) {
|
||||
err = nvme_set_feature(fd, 0, fid, (1 << 31), 0, 0, 0, 0, &result);
|
||||
err = nvme_set_feature(fd, 0, fid, (1 << 31), 0, 0, 0, 0, 0, &result);
|
||||
if (err == 0 && (err = (int)result) == 0)
|
||||
printf("Device correctable errors cleared!\n");
|
||||
else if (err > 0)
|
||||
nvme_show_status(err);
|
||||
else
|
||||
printf("Error clearing Device correctable errors = 0x%x\n", err);
|
||||
goto out;
|
||||
|
@ -1056,11 +1059,12 @@ static void init_d0_log_page(__u8 *buf, __u8 nsze)
|
|||
/* OCP and Vendor specific log data format */
|
||||
struct micron_vs_logpage {
|
||||
char *field;
|
||||
int size;
|
||||
int size; /* FB client spec version 1.0 sizes - M5410 models */
|
||||
int size2; /* FB client spec version 0.7 sizes - M5407 models */
|
||||
}
|
||||
/* Smart Health Log information as per OCP spec */
|
||||
/* Smart Health Log information as per OCP spec M51CX models */
|
||||
ocp_c0_log_page[] = {
|
||||
{ "Physical Media Units Written", 16 },
|
||||
{ "Physical Media Units Written", 16},
|
||||
{ "Physical Media Units Read", 16 },
|
||||
{ "Raw Bad User NAND Block Count", 6},
|
||||
{ "Normalized Bad User NAND Block Count", 2},
|
||||
|
@ -1096,43 +1100,56 @@ ocp_c0_log_page[] = {
|
|||
},
|
||||
/* Vendor Specific Health Log information */
|
||||
fb_log_page[] = {
|
||||
{ "Physical Media Units Written - TLC", 16 },
|
||||
{ "Physical Media Units Written - SLC", 16 },
|
||||
{ "Normalized Bad User NAND Block Count", 2},
|
||||
{ "Raw Bad User NAND Block Count", 6},
|
||||
{ "XOR Recovery Count", 8},
|
||||
{ "Uncorrectable Read Error Count", 8},
|
||||
{ "SSD End to End Corrected Errors", 8},
|
||||
{ "SSD End to End Detected Counts", 4},
|
||||
{ "SSD End to End Uncorrected Counts", 4},
|
||||
{ "System data % life-used", 1},
|
||||
{ "Minimum User Data Erase Count - TLC", 8},
|
||||
{ "Maximum User Data Erase Count - TLC", 8},
|
||||
{ "Minimum User Data Erase Count - SLC", 8},
|
||||
{ "Maximum User Data Erase Count - SLC", 8},
|
||||
{ "Normalized Program Fail Count", 2},
|
||||
{ "Raw Program Fail Count", 6},
|
||||
{ "Normalized Erase Fail Count", 2},
|
||||
{ "Raw Erase Fail Count", 6},
|
||||
{ "Pcie Correctable Error Count", 8},
|
||||
{ "% Free Blocks (User)", 1},
|
||||
{ "Security Version Number", 8},
|
||||
{ "% Free Blocks (System)", 1},
|
||||
{ "Dataset Management (Deallocate) Commands", 16},
|
||||
{ "Incomplete TRIM Data", 8},
|
||||
{ "% Age of Completed TRIM", 1},
|
||||
{ "Background Back-Pressure Gauge", 1},
|
||||
{ "Soft ECC Error Count", 8},
|
||||
{ "Refresh Count", 8},
|
||||
{ "Normalized Bad System NAND Block Count", 2},
|
||||
{ "Raw Bad System NAND Block Count", 6},
|
||||
{ "Endurance Estimate", 16},
|
||||
{ "Thermal Throttling Count", 1},
|
||||
{ "Thermal Throttling Status", 1},
|
||||
{ "Unaligned I/O", 8},
|
||||
{ "Physical Media Units Read", 16},
|
||||
{ "Reserved", 279},
|
||||
{ "Log Page Version", 2}
|
||||
{ "Physical Media Units Written - TLC", 16, 16 },
|
||||
{ "Physical Media Units Written - SLC", 16, 16 },
|
||||
{ "Normalized Bad User NAND Block Count", 2, 2},
|
||||
{ "Raw Bad User NAND Block Count", 6, 6},
|
||||
{ "XOR Recovery Count", 8, 8},
|
||||
{ "Uncorrectable Read Error Count", 8, 8},
|
||||
{ "SSD End to End Corrected Errors", 8, 8},
|
||||
{ "SSD End to End Detected Counts", 4, 8},
|
||||
{ "SSD End to End Uncorrected Counts", 4, 8},
|
||||
{ "System data % life-used", 1, 1},
|
||||
{ "Reserved", 0, 3},
|
||||
{ "Minimum User Data Erase Count - TLC", 8, 8},
|
||||
{ "Maximum User Data Erase Count - TLC", 8, 8},
|
||||
{ "Average User Data Erase Count - TLC", 0, 8},
|
||||
{ "Minimum User Data Erase Count - SLC", 8, 8},
|
||||
{ "Maximum User Data Erase Count - SLC", 8, 8},
|
||||
{ "Average User Data Erase Count - SLC", 0, 8},
|
||||
{ "Normalized Program Fail Count", 2, 2},
|
||||
{ "Raw Program Fail Count", 6, 6},
|
||||
{ "Normalized Erase Fail Count", 2, 2},
|
||||
{ "Raw Erase Fail Count", 6, 6},
|
||||
{ "Pcie Correctable Error Count", 8, 8},
|
||||
{ "% Free Blocks (User)", 1, 1},
|
||||
{ "Reserved", 0, 3},
|
||||
{ "Security Version Number", 8, 8},
|
||||
{ "% Free Blocks (System)", 1, 1},
|
||||
{ "Reserved", 0, 3},
|
||||
{ "Dataset Management (Deallocate) Commands", 16, 16},
|
||||
{ "Incomplete TRIM Data", 8, 8},
|
||||
{ "% Age of Completed TRIM", 1, 2},
|
||||
{ "Background Back-Pressure Gauge", 1, 1},
|
||||
{ "Reserved", 0, 3},
|
||||
{ "Soft ECC Error Count", 8, 8},
|
||||
{ "Refresh Count", 8, 8},
|
||||
{ "Normalized Bad System NAND Block Count", 2, 2},
|
||||
{ "Raw Bad System NAND Block Count", 6, 6},
|
||||
{ "Endurance Estimate", 16, 16},
|
||||
{ "Thermal Throttling Count", 1, 1},
|
||||
{ "Thermal Throttling Status", 1, 1},
|
||||
{ "Unaligned I/O", 8, 8},
|
||||
{ "Physical Media Units Read", 16, 16},
|
||||
{ "Reserved", 279, 0},
|
||||
{ "Log Page Version", 2, 0},
|
||||
{ "READ CMDs exceeding threshold", 0, 4},
|
||||
{ "WRITE CMDs exceeding threshold", 0, 4},
|
||||
{ "TRIMs CMDs exceeding threshold", 0, 4},
|
||||
{ "Reserved", 0, 4},
|
||||
{ "Reserved", 0, 210},
|
||||
{ "Log Page Version", 0, 2},
|
||||
{ "Log Page GUID", 0, 16},
|
||||
};
|
||||
|
||||
/* Common function to print Micron VS log pages */
|
||||
|
@ -1140,66 +1157,70 @@ static void print_micron_vs_logs(
|
|||
__u8 *buf, /* raw log data */
|
||||
struct micron_vs_logpage *log_page, /* format of the data */
|
||||
int field_count, /* log field count */
|
||||
struct json_object *stats /* json object to add fields */
|
||||
struct json_object *stats, /* json object to add fields */
|
||||
__u8 spec /* ocp spec index */
|
||||
)
|
||||
{
|
||||
__u64 lval_lo, lval_hi;
|
||||
__u32 ival;
|
||||
__u16 sval;
|
||||
__u8 cval, lval[8] = { 0 };
|
||||
int field, guid_index;
|
||||
int field;
|
||||
int offset = 0;
|
||||
|
||||
for (field = 0; field < field_count; field++) {
|
||||
char datastr[1024] = { 0 };
|
||||
if (log_page[field].size == 16) {
|
||||
if (strstr(log_page[field].field, "GUID")) {
|
||||
char *tmpstr = datastr;
|
||||
tmpstr += sprintf(datastr, "0x");
|
||||
for(guid_index = 0; guid_index < 16; guid_index++)
|
||||
tmpstr += sprintf(tmpstr, "%01X", buf[offset + guid_index]);
|
||||
char *sfield = NULL;
|
||||
int size = (spec == 0) ? log_page[field].size : log_page[field].size2;
|
||||
if (size == 0) continue;
|
||||
sfield = log_page[field].field;
|
||||
if (size == 16) {
|
||||
if (strstr(sfield, "GUID")) {
|
||||
sprintf(datastr, "0x%"PRIx64"%"PRIx64"",
|
||||
(uint64_t)le64_to_cpu(*(uint64_t *)(&buf[offset + 8])),
|
||||
(uint64_t)le64_to_cpu(*(uint64_t *)(&buf[offset])));
|
||||
} else {
|
||||
lval_lo = *((__u64 *)(&buf[offset]));
|
||||
lval_hi = *((__u64 *)(&buf[offset + 8]));
|
||||
if (lval_hi)
|
||||
sprintf(datastr, "0x%"PRIx64"_%"PRIx64"",
|
||||
sprintf(datastr, "0x%"PRIx64"%016"PRIx64"",
|
||||
le64_to_cpu(lval_hi), le64_to_cpu(lval_lo));
|
||||
else
|
||||
sprintf(datastr, "0x%"PRIx64"", le64_to_cpu(lval_lo));
|
||||
}
|
||||
} else if (log_page[field].size == 8) {
|
||||
} else if (size == 8) {
|
||||
lval_lo = *((__u64 *)(&buf[offset]));
|
||||
sprintf(datastr, "0x%"PRIx64"", le64_to_cpu(lval_lo));
|
||||
} else if (log_page[field].size == 7) {
|
||||
} else if (size == 7) {
|
||||
/* 7 bytes will be in little-endian format, with last byte as MSB */
|
||||
memcpy(&lval[0], &buf[offset], 7);
|
||||
memcpy((void *)&lval_lo, lval, 8);
|
||||
sprintf(datastr, "0x%"PRIx64"", le64_to_cpu(lval_lo));
|
||||
} else if (log_page[field].size == 6) {
|
||||
} else if (size == 6) {
|
||||
ival = *((__u32 *)(&buf[offset]));
|
||||
sval = *((__u16 *)(&buf[offset + 4]));
|
||||
lval_lo = (((__u64)sval << 32) | ival);
|
||||
sprintf(datastr, "0x%"PRIx64"", le64_to_cpu(lval_lo));
|
||||
} else if (log_page[field].size == 4) {
|
||||
} else if (size == 4) {
|
||||
ival = *((__u32 *)(&buf[offset]));
|
||||
sprintf(datastr, "0x%x", le32_to_cpu(ival));
|
||||
} else if (log_page[field].size == 2) {
|
||||
} else if (size == 2) {
|
||||
sval = *((__u16 *)(&buf[offset]));
|
||||
sprintf(datastr, "0x%04x", le16_to_cpu(sval));
|
||||
} else if (log_page[field].size == 1) {
|
||||
} else if (size == 1) {
|
||||
cval = buf[offset];
|
||||
sprintf(datastr, "0x%02x", cval);
|
||||
} else {
|
||||
sprintf(datastr, "0");
|
||||
}
|
||||
offset += log_page[field].size;
|
||||
offset += size;
|
||||
/* do not print reserved values */
|
||||
if (strstr(log_page[field].field, "Reserved"))
|
||||
if (strstr(sfield, "Reserved"))
|
||||
continue;
|
||||
if (stats != NULL) {
|
||||
json_object_add_value_string(stats, log_page[field].field, datastr);
|
||||
json_object_add_value_string(stats, sfield, datastr);
|
||||
} else {
|
||||
printf("%-40s : %-4s\n", log_page[field].field, datastr);
|
||||
printf("%-40s : %-4s\n", sfield, datastr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1219,7 +1240,7 @@ static void print_smart_cloud_health_log(__u8 *buf, bool is_json)
|
|||
logPages);
|
||||
}
|
||||
|
||||
print_micron_vs_logs(buf, ocp_c0_log_page, field_count, stats);
|
||||
print_micron_vs_logs(buf, ocp_c0_log_page, field_count, stats, 0);
|
||||
|
||||
if (is_json) {
|
||||
json_array_add_value_object(logPages, stats);
|
||||
|
@ -1229,7 +1250,7 @@ static void print_smart_cloud_health_log(__u8 *buf, bool is_json)
|
|||
}
|
||||
}
|
||||
|
||||
static void print_nand_stats_fb(__u8 *buf, __u8 *buf2, __u8 nsze, bool is_json)
|
||||
static void print_nand_stats_fb(__u8 *buf, __u8 *buf2, __u8 nsze, bool is_json, __u8 spec)
|
||||
{
|
||||
struct json_object *root;
|
||||
struct json_object *logPages;
|
||||
|
@ -1244,20 +1265,22 @@ static void print_nand_stats_fb(__u8 *buf, __u8 *buf2, __u8 nsze, bool is_json)
|
|||
logPages);
|
||||
}
|
||||
|
||||
print_micron_vs_logs(buf, fb_log_page, field_count, stats);
|
||||
print_micron_vs_logs(buf, fb_log_page, field_count, stats, spec);
|
||||
|
||||
/* print last three entries from D0 log page */
|
||||
init_d0_log_page(buf2, nsze);
|
||||
if (buf2 != NULL) {
|
||||
init_d0_log_page(buf2, nsze);
|
||||
|
||||
if (is_json) {
|
||||
for (int i = 4; i < 7; i++) {
|
||||
json_object_add_value_string(stats,
|
||||
d0_log_page[i].field,
|
||||
d0_log_page[i].datastr);
|
||||
}
|
||||
} else {
|
||||
for (int i = 4; i < 7; i++) {
|
||||
printf("%-40s : %s\n", d0_log_page[i].field, d0_log_page[i].datastr);
|
||||
if (is_json) {
|
||||
for (int i = 0; i < 7; i++) {
|
||||
json_object_add_value_string(stats,
|
||||
d0_log_page[i].field,
|
||||
d0_log_page[i].datastr);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < 7; i++) {
|
||||
printf("%-40s : %s\n", d0_log_page[i].field, d0_log_page[i].datastr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1337,14 +1360,16 @@ static int micron_nand_stats(int argc, char **argv,
|
|||
is_json = false;
|
||||
|
||||
err = nvme_identify_ctrl(fd, &ctrl);
|
||||
if (err)
|
||||
if (err) {
|
||||
printf("Error %d retrieving controller identification data\n", err);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* pull log details based on the model name */
|
||||
sscanf(argv[optind], "/dev/nvme%d", &ctrlIdx);
|
||||
if ((eModel = GetDriveModel(ctrlIdx)) == UNKNOWN_MODEL) {
|
||||
printf ("Unsupported drive model for vs-nand-stats command\n");
|
||||
close(fd);
|
||||
err = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -1353,27 +1378,29 @@ static int micron_nand_stats(int argc, char **argv,
|
|||
has_d0_log = (0 == err);
|
||||
|
||||
/* should check for firmware version if this log is supported or not */
|
||||
if (eModel == M5407 || eModel == M5410) {
|
||||
if (eModel != M5407 && eModel != M5410) {
|
||||
err = nvme_get_log(fd, NVME_NSID_ALL, 0xFB, false, NVME_NO_LOG_LSP,
|
||||
FB_log_size, logFB);
|
||||
has_fb_log = (0 == err);
|
||||
}
|
||||
|
||||
nsze = (ctrl.vs[987] == 0x12);
|
||||
|
||||
if (nsze == 0 && nsze_from_oacs)
|
||||
nsze = ((ctrl.oacs >> 3) & 0x1);
|
||||
err = 0;
|
||||
if (has_fb_log)
|
||||
print_nand_stats_fb((__u8 *)logFB, (__u8 *)extSmartLog, nsze, is_json);
|
||||
else if (has_d0_log)
|
||||
|
||||
if (has_fb_log) {
|
||||
__u8 spec = (eModel == M5410) ? 0 : 1; /* FB spec version */
|
||||
print_nand_stats_fb((__u8 *)logFB, (__u8 *)extSmartLog, nsze, is_json, spec);
|
||||
} else if (has_d0_log) {
|
||||
print_nand_stats_d0((__u8 *)extSmartLog, nsze, is_json);
|
||||
else {
|
||||
printf("Unable to retrieve extended smart log for the drive\n");
|
||||
err = -ENOTTY;
|
||||
err = 0;
|
||||
}
|
||||
out:
|
||||
close(fd);
|
||||
return err;
|
||||
if (err > 0)
|
||||
nvme_show_status(err);
|
||||
return nvme_status_to_errno(err, false);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1483,6 +1510,62 @@ static void GetErrorlogData(int fd, int entries, const char *dir)
|
|||
free(error_log);
|
||||
}
|
||||
|
||||
static void GetGenericLogs(int fd, const char *dir)
|
||||
{
|
||||
struct nvme_self_test_log self_test_log;
|
||||
struct nvme_firmware_log_page fw_log;
|
||||
struct nvme_effects_log_page effects;
|
||||
struct nvme_persistent_event_log_head pevent_log_head;
|
||||
void *pevent_log_info = NULL;
|
||||
__u32 log_len = 0;
|
||||
int err = 0 ;
|
||||
bool huge = false;
|
||||
|
||||
/* get self test log */
|
||||
if (nvme_self_test_log(fd, sizeof(self_test_log), &self_test_log) == 0) {
|
||||
WriteData((__u8*)&self_test_log, sizeof(self_test_log), dir,
|
||||
"drive_self_test.bin", "self test log");
|
||||
}
|
||||
|
||||
/* get fw slot info log */
|
||||
if (nvme_fw_log(fd, &fw_log) == 0) {
|
||||
WriteData((__u8*)&fw_log, sizeof(fw_log), dir,
|
||||
"firmware_slot_info_log.bin", "firmware log");
|
||||
}
|
||||
|
||||
/* get effects log */
|
||||
if (nvme_effects_log(fd, &effects) == 0) {
|
||||
WriteData((__u8*)&effects, sizeof(effects), dir,
|
||||
"command_effects_log.bin", "effects log");
|
||||
}
|
||||
|
||||
/* get persistent event log */
|
||||
(void)nvme_persistent_event_log(fd, NVME_PEVENT_LOG_RELEASE_CTX,
|
||||
sizeof(pevent_log_head), &pevent_log_head);
|
||||
memset(&pevent_log_head, 0, sizeof(pevent_log_head));
|
||||
err = nvme_persistent_event_log(fd, NVME_PEVENT_LOG_EST_CTX_AND_READ,
|
||||
sizeof(pevent_log_head), &pevent_log_head);
|
||||
if (err) {
|
||||
fprintf(stderr, "Setting persistent event log read ctx failed (ignored)!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
log_len = le64_to_cpu(pevent_log_head.tll);
|
||||
pevent_log_info = nvme_alloc(log_len, &huge);
|
||||
if (!pevent_log_info) {
|
||||
perror("could not alloc buffer for persistent event log page (ignored)!\n");
|
||||
return;
|
||||
}
|
||||
err = nvme_persistent_event_log(fd, NVME_PEVENT_LOG_READ,
|
||||
log_len, pevent_log_info);
|
||||
if (err == 0) {
|
||||
WriteData((__u8*)pevent_log_info, log_len, dir,
|
||||
"persistent_event_log.bin", "persistent event log");
|
||||
}
|
||||
nvme_free(pevent_log_info, huge);
|
||||
return;
|
||||
}
|
||||
|
||||
static void GetNSIDDInfo(int fd, const char *dir, int nsid)
|
||||
{
|
||||
char file[PATH_MAX] = { 0 };
|
||||
|
@ -1537,14 +1620,14 @@ static void GetOSConfig(const char *strOSDirName)
|
|||
static int micron_telemetry_log(int fd, __u8 gen, __u8 type, __u8 **data,
|
||||
int *logSize, int da)
|
||||
{
|
||||
int err;
|
||||
int err, bs = 512, offset = bs;
|
||||
unsigned short data_area[4];
|
||||
unsigned char ctrl_init = (type == 0x8);
|
||||
|
||||
__u8 *buffer = (unsigned char *)calloc(512, 1);
|
||||
__u8 *buffer = (unsigned char *)calloc(bs, 1);
|
||||
if (buffer == NULL)
|
||||
return -1;
|
||||
err = nvme_get_telemetry_log(fd, buffer, gen, ctrl_init, 512, 0);
|
||||
err = nvme_get_telemetry_log(fd, buffer, gen, ctrl_init, bs, 0);
|
||||
if (err != 0) {
|
||||
fprintf(stderr, "Failed to get telemetry log header for 0x%X\n", type);
|
||||
if (buffer != NULL) {
|
||||
|
@ -1553,10 +1636,10 @@ static int micron_telemetry_log(int fd, __u8 gen, __u8 type, __u8 **data,
|
|||
return err;
|
||||
}
|
||||
|
||||
// compute size of the log
|
||||
data_area[1] = buffer[9] << 16 | buffer[8];
|
||||
data_area[2] = buffer[11] << 16 | buffer[10];
|
||||
data_area[3] = buffer[13] << 16 | buffer[12];
|
||||
/* compute size of the log */
|
||||
data_area[1] = buffer[9] << 8 | buffer[8];
|
||||
data_area[2] = buffer[11] << 8 | buffer[10];
|
||||
data_area[3] = buffer[13] << 8 | buffer[12];
|
||||
data_area[0] = data_area[1] > data_area[2] ? data_area[1] : data_area[2];
|
||||
data_area[0] = data_area[3] > data_area[0] ? data_area[3] : data_area[0];
|
||||
|
||||
|
@ -1569,9 +1652,14 @@ static int micron_telemetry_log(int fd, __u8 gen, __u8 type, __u8 **data,
|
|||
return -1;
|
||||
}
|
||||
|
||||
*logSize = data_area[da] * 512;
|
||||
*logSize = data_area[da] * bs;
|
||||
offset = bs;
|
||||
err = 0;
|
||||
if ((buffer = (unsigned char *)realloc(buffer, (size_t)(*logSize))) != NULL) {
|
||||
err = nvme_get_telemetry_log(fd, buffer, gen, ctrl_init, *logSize, 0);
|
||||
while (err == 0 && offset != *logSize) {
|
||||
err = nvme_get_telemetry_log(fd, buffer + offset, gen, ctrl_init, bs, offset);
|
||||
offset += bs;
|
||||
}
|
||||
}
|
||||
|
||||
if (err == 0 && buffer != NULL) {
|
||||
|
@ -1594,12 +1682,13 @@ static int GetTelemetryData(int fd, const char *dir)
|
|||
__u8 log;
|
||||
char *file;
|
||||
} tmap[] = {
|
||||
{0x07, "nvme_host_telemetry.bin"},
|
||||
{0x08, "nvme_cntrl_telemetry.bin"},
|
||||
{0x07, "nvmetelemetrylog.bin"},
|
||||
{0x08, "nvmetelemetrylog.bin"},
|
||||
};
|
||||
|
||||
for(i = 0; i < (int)(sizeof(tmap)/sizeof(tmap[0])); i++) {
|
||||
err = micron_telemetry_log(fd, 0, tmap[i].log, &buffer, &logSize, 0);
|
||||
err = micron_telemetry_log(fd, (tmap[i].log == 0x07),
|
||||
tmap[i].log, &buffer, &logSize, 0);
|
||||
if (err == 0 && logSize > 0 && buffer != NULL) {
|
||||
sprintf(msg, "telemetry log: 0x%X", tmap[i].log);
|
||||
WriteData(buffer, logSize, dir, tmap[i].file, msg);
|
||||
|
@ -1646,7 +1735,7 @@ static int GetFeatureSettings(int fd, const char *dir)
|
|||
bufp = NULL;
|
||||
}
|
||||
|
||||
err = nvme_get_feature(fd, 1, fmap[i].id, 0, 0x0, len, bufp, &attrVal);
|
||||
err = nvme_get_feature(fd, 1, fmap[i].id, 0, 0x0, 0, len, bufp, &attrVal);
|
||||
if (err == 0) {
|
||||
sprintf(msg, "feature: 0x%X", fmap[i].id);
|
||||
WriteData((__u8*)&attrVal, sizeof(attrVal), dir, fmap[i].file, msg);
|
||||
|
@ -1654,7 +1743,8 @@ static int GetFeatureSettings(int fd, const char *dir)
|
|||
WriteData(bufp, len, dir, fmap[i].file, msg);
|
||||
}
|
||||
} else {
|
||||
printf("Failed to retrieve feature 0x%x data !\n", fmap[i].id);
|
||||
fprintf(stderr, "Feature 0x%x data not retrieved, error %d (ignored)!\n",
|
||||
fmap[i].id, err);
|
||||
errcnt++;
|
||||
}
|
||||
}
|
||||
|
@ -1667,20 +1757,98 @@ static int micron_drive_info(int argc, char **argv, struct command *cmd,
|
|||
const char *desc = "Get drive HW information";
|
||||
int fd, err = 0;
|
||||
struct nvme_id_ctrl ctrl = { 0 };
|
||||
struct nvme_admin_cmd admin_cmd = { 0 };
|
||||
struct fb_drive_info {
|
||||
unsigned char hw_ver_major;
|
||||
unsigned char hw_ver_minor;
|
||||
unsigned char ftl_unit_size;
|
||||
unsigned char bs_ver_major;
|
||||
unsigned char bs_ver_minor;
|
||||
} dinfo = { 0 };
|
||||
eDriveModel model = UNKNOWN_MODEL;
|
||||
bool is_json = false;
|
||||
struct json_object *root, *driveInfo;
|
||||
struct format {
|
||||
char *fmt;
|
||||
};
|
||||
|
||||
const char *fmt = "output format normal";
|
||||
struct format cfg = {
|
||||
.fmt = "normal",
|
||||
};
|
||||
|
||||
OPT_ARGS(opts) = {
|
||||
OPT_FMT("format", 'f', &cfg.fmt, fmt),
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
if ((fd = micron_parse_options(argc, argv, desc, opts, NULL)) < 0)
|
||||
if ((fd = micron_parse_options(argc, argv, desc, opts, &model)) < 0)
|
||||
return err;
|
||||
|
||||
err = nvme_identify_ctrl(fd, &ctrl);
|
||||
if (err) {
|
||||
fprintf(stderr, "ERROR : nvme_identify_ctrl() failed with 0x%x\n", err);
|
||||
if (model == UNKNOWN_MODEL) {
|
||||
fprintf(stderr, "ERROR : Unsupported drive for vs-drive-info cmd");
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("%u.%u\n", ctrl.vs[820], ctrl.vs[821]);
|
||||
if (strcmp(cfg.fmt, "json") == 0)
|
||||
is_json = true;
|
||||
|
||||
if (model == M5407) {
|
||||
admin_cmd.opcode = 0xDA,
|
||||
admin_cmd.addr = (__u64) (uintptr_t) &dinfo;
|
||||
admin_cmd.data_len = (__u32)sizeof(dinfo);
|
||||
admin_cmd.cdw12 = 3;
|
||||
err = ioctl(fd, NVME_IOCTL_ADMIN_CMD, &admin_cmd);
|
||||
if (err) {
|
||||
fprintf(stderr, "ERROR : drive-info opcode failed with 0x%x\n", err);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
err = nvme_identify_ctrl(fd, &ctrl);
|
||||
if (err) {
|
||||
fprintf(stderr, "ERROR : identify_ctrl() failed with 0x%x\n", err);
|
||||
return -1;
|
||||
}
|
||||
dinfo.hw_ver_major = ctrl.vs[820];
|
||||
dinfo.hw_ver_minor = ctrl.vs[821];
|
||||
}
|
||||
|
||||
if (is_json) {
|
||||
struct json_object *pinfo = json_create_object();
|
||||
char tempstr[64] = { 0 };
|
||||
root = json_create_object();
|
||||
driveInfo = json_create_array();
|
||||
json_object_add_value_array(root, "Micron Drive HW Information", driveInfo);
|
||||
sprintf(tempstr, "%hhu.%hhu", dinfo.hw_ver_major, dinfo.hw_ver_minor);
|
||||
json_object_add_value_string(pinfo, "Drive Hardware Version", tempstr);
|
||||
|
||||
if (dinfo.ftl_unit_size) {
|
||||
sprintf(tempstr, "%hhu KB", dinfo.ftl_unit_size);
|
||||
json_object_add_value_string(pinfo, "FTL_unit_size", tempstr);
|
||||
}
|
||||
|
||||
if (dinfo.bs_ver_major != 0 || dinfo.bs_ver_minor != 0) {
|
||||
sprintf(tempstr, "%hhu.%hhu", dinfo.bs_ver_major, dinfo.bs_ver_minor);
|
||||
json_object_add_value_string(pinfo, "Boot Spec.Version", tempstr);
|
||||
}
|
||||
|
||||
json_array_add_value_object(driveInfo, pinfo);
|
||||
json_print_object(root, NULL);
|
||||
printf("\n");
|
||||
json_free_object(root);
|
||||
} else {
|
||||
printf("Drive Hardware Version: %hhu.%hhu\n",
|
||||
dinfo.hw_ver_major, dinfo.hw_ver_minor);
|
||||
|
||||
if (dinfo.ftl_unit_size)
|
||||
printf("FTL_unit_size: %hhu KB\n", dinfo.ftl_unit_size);
|
||||
|
||||
if (dinfo.bs_ver_major != 0 || dinfo.bs_ver_minor != 0) {
|
||||
printf("Boot Spec.Version: %hhu.%hhu\n",
|
||||
dinfo.bs_ver_major, dinfo.bs_ver_minor);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1825,8 +1993,7 @@ 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;
|
||||
struct nvme_id_ctrl ctrl;
|
||||
int fd, err, ctrlIdx;
|
||||
int fd, err;
|
||||
struct format {
|
||||
char *fmt;
|
||||
};
|
||||
|
@ -1841,9 +2008,7 @@ static int micron_fw_activation_history(int argc, char **argv, struct command *c
|
|||
OPT_END()
|
||||
};
|
||||
|
||||
fd = parse_and_open(argc, argv, desc, opts);
|
||||
if (fd < 0) {
|
||||
printf("\nDevice not found \n");;
|
||||
if ((fd = micron_parse_options(argc, argv, desc, opts, &eModel)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -1853,16 +2018,8 @@ static int micron_fw_activation_history(int argc, char **argv, struct command *c
|
|||
return -1;
|
||||
}
|
||||
|
||||
err = nvme_identify_ctrl(fd, &ctrl);
|
||||
if (err) {
|
||||
fprintf(stderr, "failed get device identification data, error: %x\n", err);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* check if product supports fw_history log */
|
||||
err = -EINVAL;
|
||||
sscanf(argv[optind], "/dev/nvme%d", &ctrlIdx);
|
||||
eModel = GetDriveModel(ctrlIdx);
|
||||
if (eModel != M51CX) {
|
||||
fprintf(stderr, "Unsupported drive model for vs-fw-activate-history command\n");
|
||||
goto out;
|
||||
|
@ -1916,18 +2073,19 @@ static int micron_error_reason(int argc, char **argv, struct command *cmd,
|
|||
static int micron_ocp_smart_health_logs(int argc, char **argv, struct command *cmd,
|
||||
struct plugin *plugin)
|
||||
{
|
||||
const char *desc = "Retrieve Micron OCP Smart Health log for the given device ";
|
||||
const char *desc = "Retrieve Smart or Extended Smart Health log for the given device ";
|
||||
unsigned int logC0[C0_log_size/sizeof(int)] = { 0 };
|
||||
eDriveModel eModel = UNKNOWN_MODEL;
|
||||
unsigned int logFB[FB_log_size/sizeof(int)] = { 0 };
|
||||
struct nvme_id_ctrl ctrl;
|
||||
int fd, err, ctrlIdx;
|
||||
bool is_json = false;
|
||||
eDriveModel eModel = UNKNOWN_MODEL;
|
||||
int fd, err = 0;
|
||||
bool is_json = true;
|
||||
struct format {
|
||||
char *fmt;
|
||||
};
|
||||
const char *fmt = "output format normal|json";
|
||||
struct format cfg = {
|
||||
.fmt = "normal",
|
||||
.fmt = "json",
|
||||
};
|
||||
|
||||
OPT_ARGS(opts) = {
|
||||
|
@ -1935,41 +2093,53 @@ static int micron_ocp_smart_health_logs(int argc, char **argv, struct command *c
|
|||
OPT_END()
|
||||
};
|
||||
|
||||
fd = parse_and_open(argc, argv, desc, opts);
|
||||
if (fd < 0) {
|
||||
printf("\nDevice not found \n");;
|
||||
if ((fd = micron_parse_options(argc, argv, desc, opts, &eModel)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (strcmp(cfg.fmt, "json") == 0)
|
||||
is_json = true;
|
||||
if (strcmp(cfg.fmt, "normal") == 0)
|
||||
is_json = false;
|
||||
|
||||
err = nvme_identify_ctrl(fd, &ctrl);
|
||||
if (err)
|
||||
/* For M5410 and M5407, this option prints 0xFB log page */
|
||||
if (eModel == M5410 || eModel == M5407) {
|
||||
__u8 spec = (eModel == M5410) ? 0 : 1;
|
||||
__u8 nsze;
|
||||
|
||||
if ((err = nvme_identify_ctrl(fd, &ctrl)) == 0)
|
||||
err = nvme_get_log(fd, NVME_NSID_ALL, 0xFB, false, NVME_NO_LOG_LSP,
|
||||
FB_log_size, logFB);
|
||||
if (err) {
|
||||
if (err < 0)
|
||||
printf("Unable to retrieve smart log 0xFB for the drive\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
nsze = (ctrl.vs[987] == 0x12);
|
||||
if (nsze == 0 && nsze_from_oacs)
|
||||
nsze = ((ctrl.oacs >> 3) & 0x1);
|
||||
print_nand_stats_fb((__u8 *)logFB, NULL, nsze, is_json, spec);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* pull log details based on the model name */
|
||||
sscanf(argv[optind], "/dev/nvme%d", &ctrlIdx);
|
||||
if ((eModel = GetDriveModel(ctrlIdx)) == UNKNOWN_MODEL) {
|
||||
/* check for models that support 0xC0 log */
|
||||
if (eModel != M51CX) {
|
||||
printf ("Unsupported drive model for vs-smart-add-log commmand\n");
|
||||
close(fd);
|
||||
err = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* should check for firmware version if this log is supported or not */
|
||||
if (eModel == M5407 || eModel == M5410) {
|
||||
err = nvme_get_log(fd, NVME_NSID_ALL, 0xC0, false, NVME_NO_LOG_LSP,
|
||||
C0_log_size, logC0);
|
||||
}
|
||||
if (err < 0) {
|
||||
printf("Unable to retrieve extended smart log for the drive\n");
|
||||
err = -ENOTTY;
|
||||
} else {
|
||||
err = nvme_get_log(fd, NVME_NSID_ALL, 0xC0, false, NVME_NO_LOG_LSP,
|
||||
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);
|
||||
return err;
|
||||
if (err > 0)
|
||||
nvme_show_status(err);
|
||||
return nvme_status_to_errno(err, false);
|
||||
}
|
||||
|
||||
static int micron_clr_fw_activation_history(int argc, char **argv,
|
||||
|
@ -1994,7 +2164,7 @@ static int micron_clr_fw_activation_history(int argc, char **argv,
|
|||
}
|
||||
|
||||
//err = nvme_set_feature(fd, 1, fid, cdw11, 0, opt.save, 0, 0, &result);
|
||||
err = nvme_set_feature(fd, 1, fid, 0, 0, 0, 0, 0, &result);
|
||||
err = nvme_set_feature(fd, 1, fid, 0, 0, 0, 0, 0, 0, &result);
|
||||
if (err == 0) err = (int)result;
|
||||
return err;
|
||||
}
|
||||
|
@ -2040,14 +2210,14 @@ static int micron_telemetry_cntrl_option(int argc, char **argv,
|
|||
}
|
||||
|
||||
if (!strcmp(opt.option, "enable")) {
|
||||
err = nvme_set_feature(fd, 1, fid, 1, 0, (opt.select & 0x1), 0, 0, &result);
|
||||
err = nvme_set_feature(fd, 1, fid, 1, 0, (opt.select & 0x1), 0, 0, 0, &result);
|
||||
if (err == 0) {
|
||||
printf("successfully set controller telemetry option\n");
|
||||
} else {
|
||||
printf("Failed to set controller telemetry option\n");
|
||||
}
|
||||
} else if (!strcmp(opt.option, "disable")) {
|
||||
err = nvme_set_feature(fd, 1, fid, 0, 0, (opt.select & 0x1), 0, 0, &result);
|
||||
err = nvme_set_feature(fd, 1, fid, 0, 0, (opt.select & 0x1), 0, 0, 0, &result);
|
||||
if (err == 0) {
|
||||
printf("successfully disabled controller telemetry option\n");
|
||||
} else {
|
||||
|
@ -2055,7 +2225,7 @@ static int micron_telemetry_cntrl_option(int argc, char **argv,
|
|||
}
|
||||
} else if (!strcmp(opt.option, "status")) {
|
||||
opt.select &= 0x3;
|
||||
err = nvme_get_feature(fd, 1, fid, opt.select, 0, 0, 0, &result);
|
||||
err = nvme_get_feature(fd, 1, fid, opt.select, 0, 0, 0, 0, &result);
|
||||
if (err == 0) {
|
||||
printf("Controller telemetry option : %s\n",
|
||||
(result) ? "enabled" : "disabled");
|
||||
|
@ -2249,6 +2419,7 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd,
|
|||
|
||||
GetSmartlogData(fd, strCtrlDirName);
|
||||
GetErrorlogData(fd, ctrl.elpe, strCtrlDirName);
|
||||
GetGenericLogs(fd, strCtrlDirName);
|
||||
|
||||
// pull if telemetry log data is supported
|
||||
if ((ctrl.lpa & 0x8) == 0x8)
|
||||
|
@ -2256,7 +2427,7 @@ static int micron_internal_logs(int argc, char **argv, struct command *cmd,
|
|||
|
||||
GetFeatureSettings(fd, strCtrlDirName);
|
||||
|
||||
if (eModel != M5410) {
|
||||
if (eModel != M5410 && eModel != M5407) {
|
||||
memcpy(aVendorLogs, aM51XXLogs, sizeof(aM51XXLogs));
|
||||
if (eModel == M51AX)
|
||||
memcpy((char *)aVendorLogs + sizeof(aM51XXLogs), aM51AXLogs, sizeof(aM51AXLogs));
|
||||
|
|
|
@ -6,8 +6,9 @@
|
|||
|
||||
#include "cmd.h"
|
||||
|
||||
PLUGIN(NAME("micron", "Micron vendor specific extensions"),
|
||||
COMMAND_LIST(ENTRY("select-download", "Selective Firmware Download", micron_selective_download)
|
||||
PLUGIN(NAME("micron", "Micron vendor specific extensions", NVME_VERSION),
|
||||
COMMAND_LIST(
|
||||
ENTRY("select-download", "Selective Firmware Download", micron_selective_download)
|
||||
ENTRY("vs-temperature-stats", "Retrieve Micron temperature statistics ", micron_temp_stats)
|
||||
ENTRY("vs-pcie-stats", "Retrieve Micron PCIe error stats", micron_pcie_stats)
|
||||
ENTRY("clear-pcie-correctable-errors", "Clear correctable PCIe errors", micron_clear_pcie_correctable_errors)
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#include "cmd.h"
|
||||
|
||||
PLUGIN(NAME("netapp", "NetApp vendor specific extensions"),
|
||||
PLUGIN(NAME("netapp", "NetApp vendor specific extensions", NVME_VERSION),
|
||||
COMMAND_LIST(
|
||||
ENTRY("smdevices", "NetApp SMdevices", netapp_smdevices)
|
||||
ENTRY("ontapdevices", "NetApp ONTAPdevices", netapp_ontapdevices)
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#include "cmd.h"
|
||||
|
||||
PLUGIN(NAME("nvidia", "NVIDIA vendor specific extensions"),
|
||||
PLUGIN(NAME("nvidia", "NVIDIA vendor specific extensions", NVME_VERSION),
|
||||
COMMAND_LIST(
|
||||
ENTRY("id-ctrl", "Send NVMe Identify Controller", id_ctrl)
|
||||
)
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#include "cmd.h"
|
||||
|
||||
PLUGIN(NAME("sfx", "ScaleFlux vendor specific extensions"),
|
||||
PLUGIN(NAME("sfx", "ScaleFlux vendor specific extensions", NVME_VERSION),
|
||||
COMMAND_LIST(
|
||||
ENTRY("smart-log-add", "Retrieve ScaleFlux SMART Log, show it", get_additional_smart_log)
|
||||
ENTRY("lat-stats", "Retrieve ScaleFlux IO Latency Statistics log, show it", get_lat_stats_log)
|
||||
|
|
|
@ -1051,7 +1051,7 @@ static int vs_clr_pcie_correctable_errs(int argc, char **argv, struct command *c
|
|||
|
||||
fd = parse_and_open(argc, argv, desc, opts);
|
||||
|
||||
err = nvme_set_feature(fd, 0, 0xE1, 0xCB, 0, cfg.save, 0, buf, &result);
|
||||
err = nvme_set_feature(fd, 0, 0xE1, 0xCB, 0, cfg.save, 0, 0, buf, &result);
|
||||
|
||||
if (err < 0) {
|
||||
perror("set-feature");
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
#include "cmd.h"
|
||||
|
||||
PLUGIN(NAME("seagate", "Seagate vendor specific extensions"),
|
||||
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)
|
||||
|
|
|
@ -231,7 +231,7 @@ static int get_additional_feature(int argc, char **argv, struct command *cmd, st
|
|||
memset(buf, 0, cfg.data_len);
|
||||
}
|
||||
|
||||
err = nvme_get_feature(fd, cfg.namespace_id, cfg.feature_id, cfg.sel, cfg.cdw11,
|
||||
err = nvme_get_feature(fd, cfg.namespace_id, cfg.feature_id, cfg.sel, cfg.cdw11, 0,
|
||||
cfg.data_len, buf, &result);
|
||||
if (!err) {
|
||||
printf("get-feature:0x%02x (%s), %s value: %#08x\n", cfg.feature_id,
|
||||
|
@ -344,7 +344,7 @@ static int set_additional_feature(int argc, char **argv, struct command *cmd, st
|
|||
}
|
||||
|
||||
err = nvme_set_feature(fd, cfg.namespace_id, cfg.feature_id, cfg.value,
|
||||
0, cfg.save, cfg.data_len, buf, &result);
|
||||
0, cfg.save, 0, cfg.data_len, buf, &result);
|
||||
if (err < 0) {
|
||||
perror("set-feature");
|
||||
goto free;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#include "cmd.h"
|
||||
|
||||
PLUGIN(NAME("shannon", "Shannon vendor specific extensions"),
|
||||
PLUGIN(NAME("shannon", "Shannon vendor specific extensions", NVME_VERSION),
|
||||
COMMAND_LIST(
|
||||
ENTRY("smart-log-add", "Retrieve Shannon SMART Log, show it", get_additional_smart_log)
|
||||
ENTRY("get-feature-add", "Get Shannon feature and show the resulting value", get_additional_feature)
|
||||
|
|
|
@ -551,7 +551,7 @@ static int clear_correctable_errors(int argc, char **argv, struct command *cmd,
|
|||
goto end;
|
||||
|
||||
err = nvme_set_feature(fd, namespace_id, feature_id, value, cdw12, save,
|
||||
0, NULL, &result);
|
||||
0, 0, NULL, &result);
|
||||
if (err)
|
||||
fprintf(stderr, "%s: couldn't clear PCIe correctable errors \n",
|
||||
__func__);
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include "cmd.h"
|
||||
#include "plugin.h"
|
||||
|
||||
PLUGIN(NAME("toshiba", "Toshiba NVME plugin"),
|
||||
PLUGIN(NAME("toshiba", "Toshiba NVME plugin", NVME_VERSION),
|
||||
COMMAND_LIST(
|
||||
ENTRY("vs-smart-add-log", "Extended SMART information", vendor_log)
|
||||
ENTRY("vs-internal-log", "Get Internal Log", internal_log)
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include "cmd.h"
|
||||
|
||||
|
||||
PLUGIN(NAME("transcend", "Transcend vendor specific extensions"),
|
||||
PLUGIN(NAME("transcend", "Transcend vendor specific extensions", NVME_VERSION),
|
||||
COMMAND_LIST(
|
||||
ENTRY("healthvalue", "NVME health percentage", getHealthValue)
|
||||
ENTRY("badblock", "Get NVME bad block number", getBadblock)
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include "cmd.h"
|
||||
#include "plugin.h"
|
||||
|
||||
PLUGIN(NAME("virtium", "Virtium vendor specific extensions"),
|
||||
PLUGIN(NAME("virtium", "Virtium vendor specific extensions", NVME_VERSION),
|
||||
COMMAND_LIST(
|
||||
ENTRY("save-smart-to-vtview-log", "Periodically save smart attributes into a log file.\n\
|
||||
The data in this log file can be analyzed using excel or using Virtium’s vtView.\n\
|
||||
|
|
|
@ -79,6 +79,8 @@
|
|||
#define WDC_NVME_SN650_DEV_ID_1 0x2701
|
||||
#define WDC_NVME_SN650_DEV_ID_2 0x2702
|
||||
#define WDC_NVME_SN650_DEV_ID_3 0x2720
|
||||
#define WDC_NVME_SN450_DEV_ID_1 0x2712
|
||||
#define WDC_NVME_SN450_DEV_ID_2 0x2713
|
||||
#define WDC_NVME_SXSLCL_DEV_ID 0x2001
|
||||
#define WDC_NVME_SN520_DEV_ID 0x5003
|
||||
#define WDC_NVME_SN520_DEV_ID_1 0x5004
|
||||
|
@ -125,6 +127,7 @@
|
|||
#define WDC_DRIVE_CAP_DUI_DATA 0x0000000200000000
|
||||
#define WDC_SN730B_CAP_VUC_LOG 0x0000000400000000
|
||||
#define WDC_DRIVE_CAP_DUI 0x0000000800000000
|
||||
#define WDC_DRIVE_CAP_PURGE 0x0000001000000000
|
||||
#define WDC_DRIVE_CAP_SMART_LOG_MASK (WDC_DRIVE_CAP_C0_LOG_PAGE | WDC_DRIVE_CAP_C1_LOG_PAGE | \
|
||||
WDC_DRIVE_CAP_CA_LOG_PAGE | WDC_DRIVE_CAP_D0_LOG_PAGE)
|
||||
#define WDC_DRIVE_CAP_CLEAR_PCIE_MASK (WDC_DRIVE_CAP_CLEAR_PCIE | \
|
||||
|
@ -954,7 +957,7 @@ struct __attribute__((__packed__)) wdc_fw_act_history_log_format_c2 {
|
|||
__u8 log_identifier;
|
||||
__u8 reserved[3];
|
||||
__le32 num_entries;
|
||||
struct wdc_fw_act_history_log_entry_c2 entry[20];
|
||||
struct wdc_fw_act_history_log_entry_c2 entry[WDC_MAX_NUM_ACT_HIST_ENTRIES];
|
||||
__u8 reserved2[2790];
|
||||
__le16 log_page_version;
|
||||
__u8 log_page_guid[WDC_C2_GUID_LENGTH];
|
||||
|
@ -1181,11 +1184,13 @@ static __u64 wdc_get_drive_capabilities(int fd) {
|
|||
switch (read_device_id) {
|
||||
case WDC_NVME_SN100_DEV_ID:
|
||||
capabilities = (WDC_DRIVE_CAP_CAP_DIAG | WDC_DRIVE_CAP_INTERNAL_LOG | WDC_DRIVE_CAP_C1_LOG_PAGE |
|
||||
WDC_DRIVE_CAP_DRIVE_LOG | WDC_DRIVE_CAP_CRASH_DUMP | WDC_DRIVE_CAP_PFAIL_DUMP);
|
||||
WDC_DRIVE_CAP_DRIVE_LOG | WDC_DRIVE_CAP_CRASH_DUMP | WDC_DRIVE_CAP_PFAIL_DUMP |
|
||||
WDC_DRIVE_CAP_PURGE);
|
||||
break;
|
||||
case WDC_NVME_SN200_DEV_ID:
|
||||
capabilities = (WDC_DRIVE_CAP_CAP_DIAG | WDC_DRIVE_CAP_INTERNAL_LOG | WDC_DRIVE_CAP_CLEAR_PCIE |
|
||||
WDC_DRIVE_CAP_DRIVE_LOG | WDC_DRIVE_CAP_CRASH_DUMP | WDC_DRIVE_CAP_PFAIL_DUMP);
|
||||
WDC_DRIVE_CAP_DRIVE_LOG | WDC_DRIVE_CAP_CRASH_DUMP | WDC_DRIVE_CAP_PFAIL_DUMP |
|
||||
WDC_DRIVE_CAP_PURGE);
|
||||
|
||||
/* verify the 0xCA log page is supported */
|
||||
if (wdc_nvme_check_supported_log_page(fd, WDC_NVME_GET_DEVICE_INFO_LOG_OPCODE) == true)
|
||||
|
@ -1287,6 +1292,8 @@ static __u64 wdc_get_drive_capabilities(int fd) {
|
|||
case WDC_NVME_SN650_DEV_ID_1:
|
||||
case WDC_NVME_SN650_DEV_ID_2:
|
||||
case WDC_NVME_SN650_DEV_ID_3:
|
||||
case WDC_NVME_SN450_DEV_ID_1:
|
||||
case WDC_NVME_SN450_DEV_ID_2:
|
||||
/* verify the 0xC0 log page is supported */
|
||||
if (wdc_nvme_check_supported_log_page(fd, WDC_NVME_GET_EOL_STATUS_LOG_OPCODE) == true) {
|
||||
capabilities |= WDC_DRIVE_CAP_C0_LOG_PAGE;
|
||||
|
@ -1614,7 +1621,7 @@ static bool get_dev_mgment_cbs_data(int fd, __u8 log_id, void **cbs_data)
|
|||
memset(data, 0, sizeof (__u8) * WDC_C2_LOG_BUF_LEN);
|
||||
|
||||
/* get the log page length */
|
||||
ret = nvme_get_log14(fd, 0xFFFFFFFF, lid, NVME_NO_LOG_LSP, 0, 0, false, uuid_ix, WDC_C2_LOG_BUF_LEN, data);
|
||||
ret = nvme_get_log14(fd, 0xFFFFFFFF, lid, NVME_NO_LOG_LSP, 0, 0, false, uuid_ix, 0, false, WDC_C2_LOG_BUF_LEN, data);
|
||||
if (ret) {
|
||||
fprintf(stderr, "ERROR : WDC : Unable to get 0x%x Log Page length, ret = 0x%x\n", lid, ret);
|
||||
goto end;
|
||||
|
@ -1633,7 +1640,7 @@ static bool get_dev_mgment_cbs_data(int fd, __u8 log_id, void **cbs_data)
|
|||
}
|
||||
|
||||
/* get the log page data */
|
||||
ret = nvme_get_log14(fd, 0xFFFFFFFF, lid, NVME_NO_LOG_LSP, 0, 0, false, uuid_ix, le32_to_cpu(hdr_ptr->length), data);
|
||||
ret = nvme_get_log14(fd, 0xFFFFFFFF, lid, NVME_NO_LOG_LSP, 0, 0, false, uuid_ix, 0, false, le32_to_cpu(hdr_ptr->length), data);
|
||||
if (ret) {
|
||||
fprintf(stderr, "ERROR : WDC : Unable to read 0x%x Log Page data, ret = 0x%x\n", lid, ret);
|
||||
goto end;
|
||||
|
@ -1652,7 +1659,7 @@ static bool get_dev_mgment_cbs_data(int fd, __u8 log_id, void **cbs_data)
|
|||
/* not found with uuid = 1 try with uuid = 0 */
|
||||
uuid_ix = 0;
|
||||
/* get the log page data */
|
||||
ret = nvme_get_log14(fd, 0xFFFFFFFF, lid, NVME_NO_LOG_LSP, 0, 0, false, uuid_ix, le32_to_cpu(hdr_ptr->length), data);
|
||||
ret = nvme_get_log14(fd, 0xFFFFFFFF, lid, NVME_NO_LOG_LSP, 0, 0, false, uuid_ix, 0, false, le32_to_cpu(hdr_ptr->length), data);
|
||||
hdr_ptr = (struct wdc_c2_log_page_header *)data;
|
||||
sph = (struct wdc_c2_log_subpage_header *)(data + length);
|
||||
found = wdc_get_dev_mng_log_entry(hdr_ptr->length, log_id, hdr_ptr, &sph);
|
||||
|
@ -1980,7 +1987,7 @@ static int wdc_do_cap_telemetry_log(int fd, char *file, __u32 bs, int type, int
|
|||
} else if (type == WDC_TELEMETRY_TYPE_CONTROLLER) {
|
||||
/* Verify the Controller Initiated Option is enabled */
|
||||
err = nvme_get_feature(fd, 0, WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID, 0, 0,
|
||||
4, buf, &result);
|
||||
0, 4, buf, &result);
|
||||
if (err == 0) {
|
||||
if (result == 0) {
|
||||
/* enabled */
|
||||
|
@ -3263,15 +3270,12 @@ static int wdc_purge(int argc, char **argv,
|
|||
char *err_str;
|
||||
int fd, ret;
|
||||
struct nvme_passthru_cmd admin_cmd;
|
||||
__u64 capabilities = 0;
|
||||
|
||||
OPT_ARGS(opts) = {
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
err_str = "";
|
||||
memset(&admin_cmd, 0, sizeof (admin_cmd));
|
||||
admin_cmd.opcode = WDC_NVME_PURGE_CMD_OPCODE;
|
||||
|
||||
fd = parse_and_open(argc, argv, desc, opts);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
@ -3279,23 +3283,33 @@ static int wdc_purge(int argc, char **argv,
|
|||
if (!wdc_check_device(fd))
|
||||
return -1;
|
||||
|
||||
ret = nvme_submit_admin_passthru(fd, &admin_cmd);
|
||||
if (ret > 0) {
|
||||
switch (ret) {
|
||||
case WDC_NVME_PURGE_CMD_SEQ_ERR:
|
||||
err_str = "ERROR : WDC : Cannot execute purge, "
|
||||
"Purge operation is in progress.\n";
|
||||
break;
|
||||
case WDC_NVME_PURGE_INT_DEV_ERR:
|
||||
err_str = "ERROR : WDC : Internal Device Error.\n";
|
||||
break;
|
||||
default:
|
||||
err_str = "ERROR : WDC\n";
|
||||
}
|
||||
}
|
||||
capabilities = wdc_get_drive_capabilities(fd);
|
||||
if((capabilities & WDC_DRIVE_CAP_PURGE) == 0) {
|
||||
ret = -1;
|
||||
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
|
||||
} else {
|
||||
err_str = "";
|
||||
memset(&admin_cmd, 0, sizeof (admin_cmd));
|
||||
admin_cmd.opcode = WDC_NVME_PURGE_CMD_OPCODE;
|
||||
|
||||
fprintf(stderr, "%s", err_str);
|
||||
fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
|
||||
ret = nvme_submit_admin_passthru(fd, &admin_cmd);
|
||||
if (ret > 0) {
|
||||
switch (ret) {
|
||||
case WDC_NVME_PURGE_CMD_SEQ_ERR:
|
||||
err_str = "ERROR : WDC : Cannot execute purge, "
|
||||
"Purge operation is in progress.\n";
|
||||
break;
|
||||
case WDC_NVME_PURGE_INT_DEV_ERR:
|
||||
err_str = "ERROR : WDC : Internal Device Error.\n";
|
||||
break;
|
||||
default:
|
||||
err_str = "ERROR : WDC\n";
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "%s", err_str);
|
||||
fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -3308,19 +3322,12 @@ static int wdc_purge_monitor(int argc, char **argv,
|
|||
double progress_percent;
|
||||
struct nvme_passthru_cmd admin_cmd;
|
||||
struct wdc_nvme_purge_monitor_data *mon;
|
||||
__u64 capabilities = 0;
|
||||
|
||||
OPT_ARGS(opts) = {
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
memset(output, 0, sizeof (output));
|
||||
memset(&admin_cmd, 0, sizeof (struct nvme_admin_cmd));
|
||||
admin_cmd.opcode = WDC_NVME_PURGE_MONITOR_OPCODE;
|
||||
admin_cmd.addr = (__u64)(uintptr_t)output;
|
||||
admin_cmd.data_len = WDC_NVME_PURGE_MONITOR_DATA_LEN;
|
||||
admin_cmd.cdw10 = WDC_NVME_PURGE_MONITOR_CMD_CDW10;
|
||||
admin_cmd.timeout_ms = WDC_NVME_PURGE_MONITOR_TIMEOUT;
|
||||
|
||||
fd = parse_and_open(argc, argv, desc, opts);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
@ -3328,20 +3335,34 @@ static int wdc_purge_monitor(int argc, char **argv,
|
|||
if (!wdc_check_device(fd))
|
||||
return -1;
|
||||
|
||||
ret = nvme_submit_admin_passthru(fd, &admin_cmd);
|
||||
if (ret == 0) {
|
||||
mon = (struct wdc_nvme_purge_monitor_data *) output;
|
||||
printf("Purge state = 0x%0x\n", admin_cmd.result);
|
||||
printf("%s\n", wdc_purge_mon_status_to_string(admin_cmd.result));
|
||||
if (admin_cmd.result == WDC_NVME_PURGE_STATE_BUSY) {
|
||||
progress_percent =
|
||||
((double)le32_to_cpu(mon->entire_progress_current) * 100) /
|
||||
le32_to_cpu(mon->entire_progress_total);
|
||||
printf("Purge Progress = %f%%\n", progress_percent);
|
||||
}
|
||||
}
|
||||
capabilities = wdc_get_drive_capabilities(fd);
|
||||
if((capabilities & WDC_DRIVE_CAP_PURGE) == 0) {
|
||||
ret = -1;
|
||||
fprintf(stderr, "ERROR : WDC: unsupported device for this command\n");
|
||||
} else {
|
||||
memset(output, 0, sizeof (output));
|
||||
memset(&admin_cmd, 0, sizeof (struct nvme_admin_cmd));
|
||||
admin_cmd.opcode = WDC_NVME_PURGE_MONITOR_OPCODE;
|
||||
admin_cmd.addr = (__u64)(uintptr_t)output;
|
||||
admin_cmd.data_len = WDC_NVME_PURGE_MONITOR_DATA_LEN;
|
||||
admin_cmd.cdw10 = WDC_NVME_PURGE_MONITOR_CMD_CDW10;
|
||||
admin_cmd.timeout_ms = WDC_NVME_PURGE_MONITOR_TIMEOUT;
|
||||
|
||||
fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
|
||||
ret = nvme_submit_admin_passthru(fd, &admin_cmd);
|
||||
if (ret == 0) {
|
||||
mon = (struct wdc_nvme_purge_monitor_data *) output;
|
||||
printf("Purge state = 0x%0x\n", admin_cmd.result);
|
||||
printf("%s\n", wdc_purge_mon_status_to_string(admin_cmd.result));
|
||||
if (admin_cmd.result == WDC_NVME_PURGE_STATE_BUSY) {
|
||||
progress_percent =
|
||||
((double)le32_to_cpu(mon->entire_progress_current) * 100) /
|
||||
le32_to_cpu(mon->entire_progress_total);
|
||||
printf("Purge Progress = %f%%\n", progress_percent);
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -4006,9 +4027,9 @@ static void wdc_get_commit_action_bin(__u8 commit_action_type, char *action_bin)
|
|||
|
||||
}
|
||||
|
||||
static void wdc_print_fw_act_history_log_normal(__u8 *data, int num_entries, __u32 cust_id)
|
||||
static void wdc_print_fw_act_history_log_normal(__u8 *data, int num_entries, __u32 cust_id, __u32 vendor_id)
|
||||
{
|
||||
int i;
|
||||
int i, j;
|
||||
char previous_fw[9];
|
||||
char new_fw[9];
|
||||
char commit_action_bin[8];
|
||||
|
@ -4019,7 +4040,7 @@ static void wdc_print_fw_act_history_log_normal(__u8 *data, int num_entries, __u
|
|||
|
||||
if (data[0] == WDC_NVME_GET_FW_ACT_HISTORY_C2_LOG_ID) {
|
||||
printf(" Firmware Activate History Log \n");
|
||||
if (cust_id == WDC_CUSTOMER_ID_0x1005) {
|
||||
if (cust_id == WDC_CUSTOMER_ID_0x1005 || vendor_id == WDC_NVME_SNDK_VID) {
|
||||
printf(" Power on Hour Power Cycle Previous New \n");
|
||||
printf(" Entry hh:mm:ss Count Firmware Firmware Slot Action Result \n");
|
||||
printf(" ----- ----------------- ----------------- --------- --------- ----- ------ -------\n");
|
||||
|
@ -4028,14 +4049,16 @@ static void wdc_print_fw_act_history_log_normal(__u8 *data, int num_entries, __u
|
|||
printf(" Entry Timestamp Count Firmware Firmware Slot Action Result \n");
|
||||
printf(" ----- ----------------- ----------------- --------- --------- ----- ------ -------\n");
|
||||
}
|
||||
|
||||
struct wdc_fw_act_history_log_format_c2 *fw_act_history_entry = (struct wdc_fw_act_history_log_format_c2 *)(data);
|
||||
|
||||
if (num_entries == WDC_MAX_NUM_ACT_HIST_ENTRIES) {
|
||||
/* find lowest/oldest entry */
|
||||
for (i = 0; i < num_entries; i++) {
|
||||
j = (i+1 == WDC_MAX_NUM_ACT_HIST_ENTRIES) ? 0 : i+1;
|
||||
if (le16_to_cpu(fw_act_history_entry->entry[i].fw_act_hist_entries) >
|
||||
le16_to_cpu(fw_act_history_entry->entry[i+1].fw_act_hist_entries)) {
|
||||
oldestEntryIdx = i+1;
|
||||
le16_to_cpu(fw_act_history_entry->entry[j].fw_act_hist_entries)) {
|
||||
oldestEntryIdx = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -4066,6 +4089,14 @@ static void wdc_print_fw_act_history_log_normal(__u8 *data, int num_entries, __u
|
|||
|
||||
printf("%s", time_str);
|
||||
printf(" ");
|
||||
} else if(vendor_id == WDC_NVME_SNDK_VID) {
|
||||
printf(" ");
|
||||
uint64_t timestamp = (0x0000FFFFFFFFFFFF & le64_to_cpu(fw_act_history_entry->entry[entryIdx].timestamp));
|
||||
memset((void *)time_str, 0, 9);
|
||||
sprintf((char *)time_str, "%04d:%02d:%02d", (int)((timestamp/(3600*1000))%24), (int)((timestamp/(1000*60))%60),
|
||||
(int)((timestamp/1000)%60));
|
||||
printf("%s", time_str);
|
||||
printf(" ");
|
||||
} else {
|
||||
printf(" ");
|
||||
uint64_t timestamp = (0x0000FFFFFFFFFFFF & le64_to_cpu(fw_act_history_entry->entry[entryIdx].timestamp));
|
||||
|
@ -4161,10 +4192,10 @@ static void wdc_print_fw_act_history_log_normal(__u8 *data, int num_entries, __u
|
|||
}
|
||||
}
|
||||
|
||||
static void wdc_print_fw_act_history_log_json(__u8 *data, int num_entries, __u32 cust_id)
|
||||
static void wdc_print_fw_act_history_log_json(__u8 *data, int num_entries, __u32 cust_id, __u32 vendor_id)
|
||||
{
|
||||
struct json_object *root;
|
||||
int i;
|
||||
int i, j;
|
||||
char previous_fw[9];
|
||||
char new_fw[9];
|
||||
char commit_action_bin[8];
|
||||
|
@ -4186,9 +4217,10 @@ static void wdc_print_fw_act_history_log_json(__u8 *data, int num_entries, __u32
|
|||
if (num_entries == WDC_MAX_NUM_ACT_HIST_ENTRIES) {
|
||||
/* find lowest/oldest entry */
|
||||
for (i = 0; i < num_entries; i++) {
|
||||
j = (i+1 == WDC_MAX_NUM_ACT_HIST_ENTRIES) ? 0 : i+1;
|
||||
if (le16_to_cpu(fw_act_history_entry->entry[i].fw_act_hist_entries) >
|
||||
le16_to_cpu(fw_act_history_entry->entry[i+1].fw_act_hist_entries)) {
|
||||
oldestEntryIdx = i+1;
|
||||
le16_to_cpu(fw_act_history_entry->entry[j].fw_act_hist_entries)) {
|
||||
oldestEntryIdx = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -4215,6 +4247,11 @@ 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 if (vendor_id == WDC_NVME_SNDK_VID) {
|
||||
uint64_t timestamp = (0x0000FFFFFFFFFFFF & le64_to_cpu(fw_act_history_entry->entry[entryIdx].timestamp));
|
||||
sprintf((char *)time_str, "%04d:%02d:%02d", (int)((timestamp/(3600*1000))%24), (int)((timestamp/(1000*60))%60),
|
||||
(int)((timestamp/1000)%60));
|
||||
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);
|
||||
|
@ -4369,7 +4406,7 @@ static void wdc_print_smart_cloud_attr_C0_normal(void *data)
|
|||
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");
|
||||
printf("%lX%lX\n",(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_LPG + 8]),
|
||||
printf("0x%"PRIx64"%"PRIx64"\n",(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_LPG + 8]),
|
||||
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_LPG]));
|
||||
if(smart_log_ver > 2) {
|
||||
printf(" Errata Version Field %d\n",
|
||||
|
@ -4451,9 +4488,8 @@ static void wdc_print_smart_cloud_attr_C0_json(void *data)
|
|||
json_object_add_value_uint(root, "Log page version", smart_log_ver);
|
||||
char guid[40];
|
||||
memset((void*)guid, 0, 40);
|
||||
sprintf((char*)guid, "0x%lX%lX",(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_LPG + 8]),
|
||||
sprintf((char*)guid, "0x%"PRIx64"%"PRIx64"",(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_LPG + 8]),
|
||||
(uint64_t)le64_to_cpu(*(uint64_t *)&log_data[SCAO_LPG]));
|
||||
printf("GUID string:%s", guid);
|
||||
json_object_add_value_string(root, "Log page GUID", guid);
|
||||
if(smart_log_ver > 2){
|
||||
json_object_add_value_uint(root, "Errata Version Field",
|
||||
|
@ -4605,7 +4641,7 @@ static int wdc_get_c0_log_page(int fd, char *format, int uuid_index)
|
|||
|
||||
/* Get the 0xC0 log data */
|
||||
ret = nvme_get_log14(fd, 0xFFFFFFFF, WDC_NVME_GET_EOL_STATUS_LOG_OPCODE,
|
||||
NVME_NO_LOG_LSP, 0, 0, false, uuid_index, WDC_NVME_SMART_CLOUD_ATTR_LEN, data);
|
||||
NVME_NO_LOG_LSP, 0, 0, false, uuid_index, 0, false, WDC_NVME_SMART_CLOUD_ATTR_LEN, data);
|
||||
|
||||
if (strcmp(format, "json"))
|
||||
fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
|
||||
|
@ -4652,7 +4688,7 @@ static int wdc_get_c0_log_page(int fd, char *format, int uuid_index)
|
|||
|
||||
/* Get the 0xC0 log data */
|
||||
ret = nvme_get_log14(fd, 0xFFFFFFFF, WDC_NVME_GET_EOL_STATUS_LOG_OPCODE,
|
||||
NVME_NO_LOG_LSP, 0, 0, false, uuid_index, WDC_NVME_EOL_STATUS_LOG_LEN, data);
|
||||
NVME_NO_LOG_LSP, 0, 0, false, uuid_index, 0, false, WDC_NVME_EOL_STATUS_LOG_LEN, data);
|
||||
|
||||
if (strcmp(format, "json"))
|
||||
fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
|
||||
|
@ -4783,7 +4819,7 @@ static int wdc_print_d0_log(struct wdc_ssd_d0_smart_log *perf, int fmt)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int wdc_print_fw_act_history_log(__u8 *data, int num_entries, int fmt, __u32 cust_id)
|
||||
static int wdc_print_fw_act_history_log(__u8 *data, int num_entries, int fmt, __u32 cust_id, __u32 vendor_id)
|
||||
{
|
||||
if (!data) {
|
||||
fprintf(stderr, "ERROR : WDC : Invalid buffer to read fw activate history entries\n");
|
||||
|
@ -4792,10 +4828,10 @@ static int wdc_print_fw_act_history_log(__u8 *data, int num_entries, int fmt, __
|
|||
|
||||
switch (fmt) {
|
||||
case NORMAL:
|
||||
wdc_print_fw_act_history_log_normal(data, num_entries, cust_id);
|
||||
wdc_print_fw_act_history_log_normal(data, num_entries, cust_id, vendor_id);
|
||||
break;
|
||||
case JSON:
|
||||
wdc_print_fw_act_history_log_json(data, num_entries, cust_id);
|
||||
wdc_print_fw_act_history_log_json(data, num_entries, cust_id, vendor_id);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
|
@ -5200,7 +5236,7 @@ static int wdc_do_clear_pcie_correctable_errors_fid(int fd)
|
|||
__u32 value = 1 << 31; /* Bit 31 - clear PCIe correctable count */
|
||||
|
||||
ret = nvme_set_feature(fd, 0, WDC_NVME_CLEAR_PCIE_CORR_FEATURE_ID, value,
|
||||
0, 0, 0, NULL, &result);
|
||||
0, 0, 0, 0, NULL, &result);
|
||||
|
||||
fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
|
||||
return ret;
|
||||
|
@ -5448,7 +5484,7 @@ static int wdc_get_fw_act_history(int fd, char *format)
|
|||
fw_act_history_hdr = (struct wdc_fw_act_history_log_hdr *)(data);
|
||||
|
||||
if ((fw_act_history_hdr->num_entries > 0) && (fw_act_history_hdr->num_entries <= WDC_MAX_NUM_ACT_HIST_ENTRIES))
|
||||
ret = wdc_print_fw_act_history_log(data, fw_act_history_hdr->num_entries, fmt, 0);
|
||||
ret = wdc_print_fw_act_history_log(data, fw_act_history_hdr->num_entries, fmt, 0, 0);
|
||||
else if (fw_act_history_hdr->num_entries == 0) {
|
||||
fprintf(stderr, "INFO : WDC : No FW Activate History entries found.\n");
|
||||
ret = 0;
|
||||
|
@ -5473,7 +5509,8 @@ static int wdc_get_fw_act_history_C2(int fd, char *format)
|
|||
__u8 *data;
|
||||
__u32 *cust_id;
|
||||
struct wdc_fw_act_history_log_format_c2 *fw_act_history_log;
|
||||
__u32 num_entries = 0;
|
||||
__u32 tot_entries = 0, num_entries = 0;
|
||||
__u32 vendor_id = 0, device_id = 0;
|
||||
|
||||
if (!wdc_check_device(fd))
|
||||
return -1;
|
||||
|
@ -5483,6 +5520,7 @@ static int wdc_get_fw_act_history_C2(int fd, char *format)
|
|||
fprintf(stderr, "ERROR : WDC : invalid output format\n");
|
||||
return fmt;
|
||||
}
|
||||
ret = wdc_get_pci_ids(&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));
|
||||
|
@ -5500,25 +5538,22 @@ static int wdc_get_fw_act_history_C2(int fd, char *format)
|
|||
if (ret == 0) {
|
||||
/* parse the data */
|
||||
fw_act_history_log = (struct wdc_fw_act_history_log_format_c2*)(data);
|
||||
num_entries = le32_to_cpu(fw_act_history_log->num_entries);
|
||||
tot_entries = le32_to_cpu(fw_act_history_log->num_entries);
|
||||
|
||||
if ((num_entries > 0) && (num_entries <= WDC_MAX_NUM_ACT_HIST_ENTRIES)) {
|
||||
if (tot_entries > 0) {
|
||||
/* get the FW customer id */
|
||||
if (!get_dev_mgment_cbs_data(fd, WDC_C2_CUSTOMER_ID_ID, (void*)&cust_id)) {
|
||||
fprintf(stderr, "%s: ERROR : WDC : 0xC2 Log Page entry ID 0x%x not found\n", __func__, WDC_C2_CUSTOMER_ID_ID);
|
||||
ret = -1;
|
||||
goto freeData;
|
||||
}
|
||||
|
||||
ret = wdc_print_fw_act_history_log(data, num_entries, fmt, *cust_id);
|
||||
} else if (num_entries == 0) {
|
||||
num_entries = (tot_entries < WDC_MAX_NUM_ACT_HIST_ENTRIES) ? tot_entries :
|
||||
WDC_MAX_NUM_ACT_HIST_ENTRIES;
|
||||
ret = wdc_print_fw_act_history_log(data, num_entries, fmt, *cust_id, vendor_id);
|
||||
} else {
|
||||
fprintf(stderr, "INFO : WDC : No FW Activate History entries found.\n");
|
||||
ret = 0;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "ERROR : WDC : Invalid number entries found in FW Activate History Log Page - %d\n", num_entries);
|
||||
ret = -1;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "ERROR : WDC : Unable to read FW Activate History Log Page data\n");
|
||||
ret = -1;
|
||||
|
@ -5578,7 +5613,7 @@ static int wdc_vs_fw_activate_history(int argc, char **argv, struct command *com
|
|||
|
||||
/* Get the 0xC0 log data */
|
||||
ret = nvme_get_log14(fd, 0xFFFFFFFF, WDC_NVME_GET_SMART_CLOUD_ATTR_LOG_OPCODE,
|
||||
NVME_NO_LOG_LSP, 0, 0, false, uuid_index, WDC_NVME_SMART_CLOUD_ATTR_LEN, data);
|
||||
NVME_NO_LOG_LSP, 0, 0, false, uuid_index, 0, false, WDC_NVME_SMART_CLOUD_ATTR_LEN, data);
|
||||
|
||||
if (ret == 0) {
|
||||
/* Verify GUID matches */
|
||||
|
@ -5634,7 +5669,7 @@ static int wdc_do_clear_fw_activate_history_fid(int fd)
|
|||
__u32 value = 1 << 31; /* Bit 31 - Clear Firmware Update History Log */
|
||||
|
||||
ret = nvme_set_feature(fd, 0, WDC_NVME_CLEAR_FW_ACT_HIST_VU_FID, value,
|
||||
0, 0, 0, NULL, &result);
|
||||
0, 0, 0, 0, NULL, &result);
|
||||
|
||||
fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(ret), ret);
|
||||
return ret;
|
||||
|
@ -5728,18 +5763,18 @@ static int wdc_vs_telemetry_controller_option(int argc, char **argv, struct comm
|
|||
|
||||
if (cfg.disable) {
|
||||
ret = nvme_set_feature(fd, 0, WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID, 1,
|
||||
0, 0, 0, buf, &result);
|
||||
0, 0, 0, 0, buf, &result);
|
||||
|
||||
wdc_clear_reason_id(fd);
|
||||
}
|
||||
else {
|
||||
if (cfg.enable) {
|
||||
ret = nvme_set_feature(fd, 0, WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID, 0,
|
||||
0, 0, 0, buf, &result);
|
||||
0, 0, 0, 0, buf, &result);
|
||||
}
|
||||
else if (cfg.status) {
|
||||
ret = nvme_get_feature(fd, 0, WDC_VU_DISABLE_CNTLR_TELEMETRY_OPTION_FEATURE_ID, 0, 0,
|
||||
4, buf, &result);
|
||||
0, 4, buf, &result);
|
||||
if (ret == 0) {
|
||||
if (result)
|
||||
fprintf(stderr, "Controller Option Telemetry Log Page State: Disabled\n");
|
||||
|
@ -6363,7 +6398,7 @@ static int wdc_do_drive_essentials(int fd, char *dir, char *key)
|
|||
if (deFeatureIdList[listIdx].featureId == FID_LBA_RANGE_TYPE)
|
||||
continue;
|
||||
ret = nvme_get_feature(fd, WDC_DE_GLOBAL_NSID, deFeatureIdList[listIdx].featureId, FS_CURRENT, 0,
|
||||
sizeof(featureIdBuff), &featureIdBuff, &result);
|
||||
0, sizeof(featureIdBuff), &featureIdBuff, &result);
|
||||
|
||||
if (ret) {
|
||||
fprintf(stderr, "ERROR : WDC : nvme_get_feature id 0x%x failed, ret = %d\n",
|
||||
|
@ -7713,7 +7748,7 @@ 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_feature(fd, 0, 0x10, 0, 0, 0, 0, &hctm_tmt);
|
||||
nvme_get_feature(fd, 0, 0x10, 0, 0, 0, 0, 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;
|
||||
|
||||
|
@ -7800,8 +7835,10 @@ static int wdc_capabilities(int argc, char **argv,
|
|||
printf("get-pfail-dump : %s\n",
|
||||
capabilities & WDC_DRIVE_CAP_PFAIL_DUMP ? "Supported" : "Not Supported");
|
||||
printf("id-ctrl : Supported\n");
|
||||
printf("purge : Supported\n");
|
||||
printf("purge-monitor : Supported\n");
|
||||
printf("purge : %s\n",
|
||||
capabilities & WDC_DRIVE_CAP_PURGE ? "Supported" : "Not Supported");
|
||||
printf("purge-monitor : %s\n",
|
||||
capabilities & WDC_DRIVE_CAP_PURGE ? "Supported" : "Not Supported");
|
||||
printf("vs-internal-log : %s\n",
|
||||
capabilities & WDC_DRIVE_CAP_INTERNAL_LOG_MASK ? "Supported" : "Not Supported");
|
||||
printf("vs-nand-stats : %s\n",
|
||||
|
|
|
@ -4,9 +4,10 @@
|
|||
#if !defined(WDC_NVME) || defined(CMD_HEADER_MULTI_READ)
|
||||
#define WDC_NVME
|
||||
|
||||
#define WDC_PLUGIN_VERSION "1.14.1"
|
||||
#include "cmd.h"
|
||||
|
||||
PLUGIN(NAME("wdc", "Western Digital vendor specific extensions"),
|
||||
PLUGIN(NAME("wdc", "Western Digital vendor specific extensions", WDC_PLUGIN_VERSION),
|
||||
COMMAND_LIST(
|
||||
ENTRY("cap-diag", "WDC Capture-Diagnostics", wdc_cap_diag)
|
||||
ENTRY("drive-log", "WDC Drive Log", wdc_drive_log)
|
||||
|
|
|
@ -77,7 +77,11 @@ int wdc_UtilsGetTime(PUtilsTimeInfo timeInfo)
|
|||
timeInfo->second = currTimeInfo.tm_sec;
|
||||
timeInfo->msecs = 0;
|
||||
timeInfo->isDST = currTimeInfo.tm_isdst;
|
||||
#if defined(__GLIBC__) && !defined(__UCLIBC__) && !defined(__MUSL__)
|
||||
timeInfo->zone = -currTimeInfo.tm_gmtoff / 60;
|
||||
#else
|
||||
timeInfo->zone = -1 * (timezone / SECONDS_IN_MIN);
|
||||
#endif
|
||||
|
||||
return WDC_STATUS_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
PLUGIN(NAME("ymtc", "Ymtc vendor specific extensions"),
|
||||
PLUGIN(NAME("ymtc", "Ymtc vendor specific extensions", NVME_VERSION),
|
||||
COMMAND_LIST(
|
||||
ENTRY("smart-log-add", "Retrieve Ymtc SMART Log, show it", get_additional_smart_log)
|
||||
)
|
||||
|
|
|
@ -130,12 +130,13 @@ close_fd:
|
|||
return nvme_status_to_errno(err, false);
|
||||
}
|
||||
|
||||
static int __zns_mgmt_send(int fd, __u32 namespace_id, __u64 zslba,
|
||||
bool select_all, enum nvme_zns_send_action zsa, __u32 data_len, void *buf)
|
||||
static int __zns_mgmt_send(int fd, __u32 namespace_id, __u64 zslba,
|
||||
bool select_all, __u32 timeout, enum nvme_zns_send_action zsa,
|
||||
__u32 data_len, void *buf)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = nvme_zns_mgmt_send(fd, namespace_id, zslba, select_all, zsa,
|
||||
err = nvme_zns_mgmt_send(fd, namespace_id, zslba, select_all, timeout, zsa,
|
||||
data_len, buf);
|
||||
close(fd);
|
||||
return err;
|
||||
|
@ -146,6 +147,7 @@ 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;
|
||||
char *command;
|
||||
|
@ -154,15 +156,16 @@ static int zns_mgmt_send(int argc, char **argv, struct command *cmd, struct plug
|
|||
__u64 zslba;
|
||||
__u32 namespace_id;
|
||||
bool select_all;
|
||||
__u32 timeout;
|
||||
};
|
||||
|
||||
struct config cfg = {
|
||||
};
|
||||
struct config cfg = {};
|
||||
|
||||
OPT_ARGS(opts) = {
|
||||
OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),
|
||||
OPT_SUFFIX("start-lba", 's', &cfg.zslba, zslba),
|
||||
OPT_FLAG("select-all", 'a', &cfg.select_all, select_all),
|
||||
OPT_UINT("timeout", 't', &cfg.timeout, timeout),
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
|
@ -183,7 +186,7 @@ static int zns_mgmt_send(int argc, char **argv, struct command *cmd, struct plug
|
|||
}
|
||||
|
||||
err = __zns_mgmt_send(fd, cfg.namespace_id, cfg.zslba,
|
||||
cfg.select_all, zsa, 0, NULL);
|
||||
cfg.select_all, cfg.timeout, zsa, 0, NULL);
|
||||
if (!err)
|
||||
printf("%s: Success, action:%d zone:%"PRIx64" all:%d nsid:%d\n",
|
||||
command, zsa, (uint64_t)cfg.zslba, (int)cfg.select_all,
|
||||
|
@ -207,23 +210,21 @@ static int get_zdes_bytes(int fd, __u32 nsid)
|
|||
int err;
|
||||
|
||||
err = nvme_identify_ns(fd, nsid, false, &id_ns);
|
||||
if (err > 0){
|
||||
if (err > 0) {
|
||||
nvme_show_status(err);
|
||||
return err;
|
||||
}
|
||||
else if (err < 0){
|
||||
return -1;
|
||||
} else if (err < 0) {
|
||||
perror("identify namespace");
|
||||
return err;
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = nvme_zns_identify_ns(fd, nsid, &ns);
|
||||
if (err > 0){
|
||||
if (err > 0) {
|
||||
nvme_show_status(err);
|
||||
return err;
|
||||
}
|
||||
else if (err < 0){
|
||||
return -1;
|
||||
} else if (err < 0) {
|
||||
perror("zns identify namespace");
|
||||
return err;
|
||||
return -1;
|
||||
}
|
||||
|
||||
lbaf = id_ns.flbas & NVME_NS_FLBAS_LBA_MASK;
|
||||
|
@ -238,6 +239,7 @@ static int zone_mgmt_send(int argc, char **argv, struct command *cmd, struct plu
|
|||
const char *zsa = "zone send action";
|
||||
const char *data_len = "buffer length if data required";
|
||||
const char *data = "optional file for data (default stdin)";
|
||||
const char *timeout = "timeout value, in milliseconds";
|
||||
|
||||
int fd, ffd = STDIN_FILENO, err = -1;
|
||||
void *buf = NULL;
|
||||
|
@ -247,20 +249,21 @@ static int zone_mgmt_send(int argc, char **argv, struct command *cmd, struct plu
|
|||
__u32 namespace_id;
|
||||
bool select_all;
|
||||
__u8 zsa;
|
||||
int data_len;
|
||||
int data_len;
|
||||
char *file;
|
||||
__u32 timeout;
|
||||
};
|
||||
|
||||
struct config cfg = {
|
||||
};
|
||||
struct config cfg = {};
|
||||
|
||||
OPT_ARGS(opts) = {
|
||||
OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),
|
||||
OPT_SUFFIX("start-lba", 's', &cfg.zslba, zslba),
|
||||
OPT_FLAG("select-all", 'a', &cfg.select_all, select_all),
|
||||
OPT_BYTE("zsa", 'z', &cfg.zsa, zsa),
|
||||
OPT_UINT("data-len", 'l', &cfg.data_len, data_len),
|
||||
OPT_FILE("data", 'd', &cfg.file, data),
|
||||
OPT_UINT("data-len", 'l', &cfg.data_len, data_len),
|
||||
OPT_FILE("data", 'd', &cfg.file, data),
|
||||
OPT_UINT("timeout", 't', &cfg.timeout, timeout),
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
|
@ -285,9 +288,9 @@ static int zone_mgmt_send(int argc, char **argv, struct command *cmd, struct plu
|
|||
if (cfg.zsa == NVME_ZNS_ZSA_SET_DESC_EXT) {
|
||||
if(!cfg.data_len) {
|
||||
cfg.data_len = get_zdes_bytes(fd, cfg.namespace_id);
|
||||
if (cfg.data_len == 0) {
|
||||
if (!cfg.data_len || cfg.data_len < 0) {
|
||||
fprintf(stderr,
|
||||
"Zone Descriptor Extensions are not supported\n");
|
||||
"Zone Descriptor Extensions are not supported\n");
|
||||
goto close_fd;
|
||||
} else if (cfg.data_len < 0) {
|
||||
err = cfg.data_len;
|
||||
|
@ -323,7 +326,7 @@ static int zone_mgmt_send(int argc, char **argv, struct command *cmd, struct plu
|
|||
}
|
||||
|
||||
err = __zns_mgmt_send(fd, cfg.namespace_id, cfg.zslba, cfg.select_all,
|
||||
cfg.zsa, cfg.data_len, buf);
|
||||
cfg.timeout, cfg.zsa, cfg.data_len, buf);
|
||||
if (!err)
|
||||
printf("zone-mgmt-send: Success, action:%d zone:%"PRIx64" "
|
||||
"all:%d nsid:%d\n",
|
||||
|
@ -384,6 +387,7 @@ static int set_zone_desc(int argc, char **argv, struct command *cmd, struct plug
|
|||
const char *desc = "Set Zone Descriptor Extension\n";
|
||||
const char *zslba = "starting LBA of the zone for this command";
|
||||
const char *data = "optional file for zone extention data (default stdin)";
|
||||
const char *timeout = "timeout value, in milliseconds";
|
||||
|
||||
int fd, ffd = STDIN_FILENO, err;
|
||||
void *buf = NULL;
|
||||
|
@ -393,15 +397,16 @@ static int set_zone_desc(int argc, char **argv, struct command *cmd, struct plug
|
|||
__u64 zslba;
|
||||
__u32 namespace_id;
|
||||
char *file;
|
||||
__u32 timeout;
|
||||
};
|
||||
|
||||
struct config cfg = {
|
||||
};
|
||||
struct config cfg = {};
|
||||
|
||||
OPT_ARGS(opts) = {
|
||||
OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),
|
||||
OPT_SUFFIX("start-lba", 's', &cfg.zslba, zslba),
|
||||
OPT_FILE("data", 'd', &cfg.file, data),
|
||||
OPT_FILE("data", 'd', &cfg.file, data),
|
||||
OPT_UINT("timeout", 't', &cfg.timeout, timeout),
|
||||
OPT_END()
|
||||
};
|
||||
|
||||
|
@ -419,7 +424,7 @@ static int set_zone_desc(int argc, char **argv, struct command *cmd, struct plug
|
|||
|
||||
data_len = get_zdes_bytes(fd, cfg.namespace_id);
|
||||
|
||||
if (!data_len) {
|
||||
if (!data_len || data_len < 0) {
|
||||
fprintf(stderr,
|
||||
"zone format does not provide descriptor extention\n");
|
||||
errno = EINVAL;
|
||||
|
@ -449,7 +454,7 @@ static int set_zone_desc(int argc, char **argv, struct command *cmd, struct plug
|
|||
goto close_ffd;
|
||||
}
|
||||
|
||||
err = __zns_mgmt_send(fd, cfg.namespace_id, cfg.zslba, 0,
|
||||
err = __zns_mgmt_send(fd, cfg.namespace_id, cfg.zslba, 0, cfg.timeout,
|
||||
NVME_ZNS_ZSA_SET_DESC_EXT, data_len, buf);
|
||||
if (!err)
|
||||
printf("set-zone-desc: Success, zone:%"PRIx64" nsid:%d\n",
|
||||
|
@ -708,8 +713,7 @@ static int zone_append(int argc, char **argv, struct command *cmd, struct plugin
|
|||
int latency;
|
||||
};
|
||||
|
||||
struct config cfg = {
|
||||
};
|
||||
struct config cfg = {};
|
||||
|
||||
OPT_ARGS(opts) = {
|
||||
OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#include "cmd.h"
|
||||
|
||||
PLUGIN(NAME("zns", "Zoned Namespace Command Set"),
|
||||
PLUGIN(NAME("zns", "Zoned Namespace Command Set", NVME_VERSION),
|
||||
COMMAND_LIST(
|
||||
ENTRY("id-ctrl", "Retrieve ZNS controller identification", id_ctrl)
|
||||
ENTRY("id-ns", "Retrieve ZNS namespace identification", id_ns)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue