diff options
Diffstat (limited to 'plugins/ocp')
-rw-r--r-- | plugins/ocp/meson.build | 6 | ||||
-rw-r--r-- | plugins/ocp/ocp-clear-fw-update-history.c | 73 | ||||
-rw-r--r-- | plugins/ocp/ocp-clear-fw-update-history.h | 9 | ||||
-rw-r--r-- | plugins/ocp/ocp-nvme.c | 7 | ||||
-rw-r--r-- | plugins/ocp/ocp-nvme.h | 11 | ||||
-rw-r--r-- | plugins/ocp/ocp-utils.c | 30 | ||||
-rw-r--r-- | plugins/ocp/ocp-utils.h | 18 |
7 files changed, 150 insertions, 4 deletions
diff --git a/plugins/ocp/meson.build b/plugins/ocp/meson.build new file mode 100644 index 0000000..a4e5d20 --- /dev/null +++ b/plugins/ocp/meson.build @@ -0,0 +1,6 @@ +sources += [ + 'plugins/ocp/ocp-utils.c', + 'plugins/ocp/ocp-nvme.c', + 'plugins/ocp/ocp-clear-fw-update-history.c', +] + diff --git a/plugins/ocp/ocp-clear-fw-update-history.c b/plugins/ocp/ocp-clear-fw-update-history.c new file mode 100644 index 0000000..fef09cf --- /dev/null +++ b/plugins/ocp/ocp-clear-fw-update-history.c @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2022 Solidigm. + * + * Authors: haro.panosyan@solidigm.com + * leonardo.da.cunha@solidigm.com + */ + +#include <unistd.h> +#include "ocp-utils.h" +#include "nvme-print.h" + +static const __u8 OCP_FID_CLEAR_FW_ACTIVATION_HISTORY = 0xC1; + +int ocp_clear_fw_update_history(int argc, char **argv, struct command *cmd, struct plugin *plugin) +{ + const char *desc = "OCP Clear Firmware Update History"; + __u32 result = 0; + __u32 clear_fw_history = 1 << 31; + struct nvme_dev *dev; + int uuid_index = 0; + bool no_uuid = false; + int err; + + OPT_ARGS(opts) = { + OPT_FLAG("no-uuid", 'n', &no_uuid, + "Skip UUID index search (UUID index not required for OCP 1.0)"), + OPT_END() + }; + + err = parse_and_open(&dev, argc, argv, desc, opts); + if (err) + return err; + if (no_uuid == false) { + // OCP 2.0 requires UUID index support + err = ocp_get_uuid_index(dev, &uuid_index); + if (err || uuid_index == 0) { + fprintf(stderr, "ERROR: No OCP UUID index found\n"); + goto close_dev; + } + } + + struct nvme_set_features_args args = { + .result = &result, + .data = NULL, + .args_size = sizeof(args), + .fd = dev_fd(dev), + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .nsid = 0, + .cdw11 = clear_fw_history, + .cdw12 = 0, + .cdw13 = 0, + .cdw15 = 0, + .data_len = 0, + .save = 0, + .uuidx = uuid_index, + .fid = OCP_FID_CLEAR_FW_ACTIVATION_HISTORY, + }; + + err = nvme_set_features(&args); + + if (err == 0) + printf("Success : %s\n", desc); + else if (err > 0) + nvme_show_status(err); + else + printf("Fail : %s\n", desc); +close_dev: + /* Redundant close() to make static code analysis happy */ + close(dev->direct.fd); + dev_close(dev); + return err; +} diff --git a/plugins/ocp/ocp-clear-fw-update-history.h b/plugins/ocp/ocp-clear-fw-update-history.h new file mode 100644 index 0000000..25fb6b1 --- /dev/null +++ b/plugins/ocp/ocp-clear-fw-update-history.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2022 Solidigm. + * + * Authors: haro.panosyan@solidigm.com + * leonardo.da.cunha@solidigm.com + */ + +int ocp_clear_fw_update_history(int argc, char **argv, struct command *cmd, struct plugin *plugin); diff --git a/plugins/ocp/ocp-nvme.c b/plugins/ocp/ocp-nvme.c index 5cbf6cb..14a5f30 100644 --- a/plugins/ocp/ocp-nvme.c +++ b/plugins/ocp/ocp-nvme.c @@ -22,6 +22,7 @@ #include "linux/types.h" #include "util/types.h" #include "nvme-print.h" +#include "ocp-clear-fw-update-history.h" #define CREATE_CMD #include "ocp-nvme.h" @@ -765,3 +766,9 @@ static int ocp_latency_monitor_log(int argc, char **argv, struct command *comman dev_close(dev); return ret; } + +static int clear_fw_update_history(int argc, char **argv, struct command *cmd, + struct plugin *plugin) +{ + return ocp_clear_fw_update_history(argc, argv, cmd, plugin); +} diff --git a/plugins/ocp/ocp-nvme.h b/plugins/ocp/ocp-nvme.h index 3e3f437..c20646a 100644 --- a/plugins/ocp/ocp-nvme.h +++ b/plugins/ocp/ocp-nvme.h @@ -14,10 +14,13 @@ #include "cmd.h" PLUGIN(NAME("ocp", "OCP cloud SSD extensions", NVME_VERSION), - COMMAND_LIST( - ENTRY("smart-add-log", "Retrieve extended SMART Information", ocp_smart_add_log) - ENTRY("latency-monitor-log", "Get Latency Monitor Log Page", ocp_latency_monitor_log) - ) + COMMAND_LIST( + ENTRY("smart-add-log", "Retrieve extended SMART Information", ocp_smart_add_log) + ENTRY("latency-monitor-log", "Get Latency Monitor Log Page", + ocp_latency_monitor_log) + ENTRY("clear-fw-activate-history", "Clear firmware update history log", + clear_fw_update_history) + ) ); #endif diff --git a/plugins/ocp/ocp-utils.c b/plugins/ocp/ocp-utils.c new file mode 100644 index 0000000..9294c05 --- /dev/null +++ b/plugins/ocp/ocp-utils.c @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2022 Solidigm. + * + * Author: leonardo.da.cunha@solidigm.com + */ + +#include "ocp-utils.h" + +const unsigned char ocp_uuid[NVME_UUID_LEN] = { + 0x6f, 0xbe, 0x56, 0x8f, 0x99, 0x29, 0x1d, 0xa2, 0x94, 0x47, + 0x94, 0xe0, 0x5b, 0xd5, 0x94, 0xc1 }; + +int ocp_get_uuid_index(struct nvme_dev *dev, int *index) +{ + struct nvme_id_uuid_list uuid_list; + int err = nvme_identify_uuid(dev_fd(dev), &uuid_list); + + *index = 0; + if (err) + return err; + + for (int i = 0; i < NVME_ID_UUID_LIST_MAX; i++) { + if (memcmp(ocp_uuid, &uuid_list.entry[i].uuid, NVME_UUID_LEN) == 0) { + *index = i + 1; + break; + } + } + return err; +} diff --git a/plugins/ocp/ocp-utils.h b/plugins/ocp/ocp-utils.h new file mode 100644 index 0000000..44d0af4 --- /dev/null +++ b/plugins/ocp/ocp-utils.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2022 Solidigm. + * + * Author: leonardo.da.cunha@solidigm.com + */ + +#include "nvme.h" + +/** + * ocp_get_uuid_index() - Get OCP UUID index + * @dev: nvme device + * @index: integer ponter to here to save the index + * @result: The command completion result from CQE dword0 + * + * Return: Zero if nvme device has UUID list log page, or result of get uuid list otherwise. + */ +int ocp_get_uuid_index(struct nvme_dev *dev, int *index); |