From 095ca1f5afcf689f2f2a78cf0c5fdd2f9bcd50be Mon Sep 17 00:00:00 2001 From: jeff-lien-sndk Date: Mon, 2 Feb 2026 12:51:55 -0600 Subject: [PATCH 1/3] sndk: Add support for additional UUID The UUID used by the SN640 and SN655 drives was not being checked in the sandisk plugin code. Signed-off-by: jeff-lien-sndk --- plugins/sandisk/sandisk-nvme.h | 2 +- plugins/sandisk/sandisk-utils.c | 25 +++++++++++++++++++------ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/plugins/sandisk/sandisk-nvme.h b/plugins/sandisk/sandisk-nvme.h index 0101b7e7bd..2691bc74b6 100644 --- a/plugins/sandisk/sandisk-nvme.h +++ b/plugins/sandisk/sandisk-nvme.h @@ -5,7 +5,7 @@ #if !defined(SANDISK_NVME) || defined(CMD_HEADER_MULTI_READ) #define SANDISK_NVME -#define SANDISK_PLUGIN_VERSION "3.1.0" +#define SANDISK_PLUGIN_VERSION "3.1.1" #include "cmd.h" PLUGIN(NAME("sndk", "Sandisk vendor specific extensions", SANDISK_PLUGIN_VERSION), diff --git a/plugins/sandisk/sandisk-utils.c b/plugins/sandisk/sandisk-utils.c index 4efc687080..d61827d442 100644 --- a/plugins/sandisk/sandisk-utils.c +++ b/plugins/sandisk/sandisk-utils.c @@ -24,6 +24,12 @@ static const __u8 WDC_UUID[NVME_UUID_LEN] = { 0xab, 0xe6, 0x33, 0x29, 0x9a, 0x70, 0xdf, 0xd0 }; +/* WDC_UUID value for SN640_3 devices and SN655 devices */ +static const __u8 WDC_UUID_SN640_3[NVME_UUID_LEN] = { + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 +}; + /* Sandisk UUID value */ static const __u8 SNDK_UUID[NVME_UUID_LEN] = { 0xde, 0x87, 0xd1, 0xeb, 0x72, 0xc5, 0x58, 0x0b, @@ -334,6 +340,9 @@ bool sndk_get_dev_mgment_data(struct nvme_global_ctx *ctx, struct nvme_transport * check for the WDC UUID second. */ uuid_index = nvme_uuid_find(&uuid_list, WDC_UUID); + if (uuid_index < 0) + /* Check for the UUID used on SN640 and SN655 drives */ + uuid_index = nvme_uuid_find(&uuid_list, WDC_UUID_SN640_3); } if (uuid_index >= 0) @@ -671,11 +680,15 @@ __u64 sndk_get_enc_drive_capabilities(struct nvme_global_ctx *ctx, /* check for the Sandisk UUID first */ uuid_index = nvme_uuid_find(&uuid_list, SNDK_UUID); - if (uuid_index < 0) + if (uuid_index < 0) { /* The Sandisk UUID is not found; * check for the WDC UUID second. */ uuid_index = nvme_uuid_find(&uuid_list, WDC_UUID); + if (uuid_index < 0) + /* Check for the UUID used on SN640 and SN655 drives */ + uuid_index = nvme_uuid_find(&uuid_list, WDC_UUID_SN640_3); + } } else { /* UUID Lists not supported, Use default uuid index - 0 */ fprintf(stderr, "INFO: SNDK: %s: UUID Lists not supported\n", @@ -718,6 +731,11 @@ __u64 sndk_get_enc_drive_capabilities(struct nvme_global_ctx *ctx, (void *)&drive_form_factor)) fprintf(stderr, "ERROR: SNDK: Getting Form Factor Failed\n"); + /* verify the 0xC0 log page is supported */ + if (run_wdc_nvme_check_supported_log_page(ctx, hdl, + SNDK_NVME_GET_SMART_CLOUD_ATTR_LOG_ID, 0)) + capabilities |= SNDK_DRIVE_CAP_C0_LOG_PAGE; + /* verify the 0xC3 log page is supported */ if (run_wdc_nvme_check_supported_log_page(ctx, hdl, SNDK_LATENCY_MON_LOG_ID, 0)) @@ -753,11 +771,6 @@ __u64 sndk_get_enc_drive_capabilities(struct nvme_global_ctx *ctx, SNDK_DRIVE_CAP_VU_FID_CLEAR_FW_ACT_HISTORY | SNDK_DRIVE_CAP_VU_FID_CLEAR_PCIE); - /* verify the 0xC0 log page is supported */ - if (run_wdc_nvme_check_supported_log_page(ctx, hdl, - SNDK_LATENCY_MON_LOG_ID, 0)) - capabilities |= SNDK_DRIVE_CAP_C0_LOG_PAGE; - if ((drive_form_factor == SNDK_C2_FORM_FACTOR_SFF_U2) || (drive_form_factor == SNDK_C2_FORM_FACTOR_EDSFF_E3S)) capabilities |= SNDK_DRIVE_CAP_RESIZE_SN861; From 5bd43a69d382a2aa1a26f21d3764fcc1e7f83216 Mon Sep 17 00:00:00 2001 From: jeff-lien-sndk Date: Mon, 2 Feb 2026 13:52:43 -0600 Subject: [PATCH 2/3] sndk: Add Clear Assert Capability to 2 Sandisk Drives 2 Sandisk drives do support the Clear Assert VUC but did not capability enabled. This change will enable it. Signed-off-by: jeff-lien-sndk --- plugins/sandisk/sandisk-utils.c | 2 ++ plugins/wdc/wdc-nvme.c | 1 + 2 files changed, 3 insertions(+) diff --git a/plugins/sandisk/sandisk-utils.c b/plugins/sandisk/sandisk-utils.c index d61827d442..674b0934a8 100644 --- a/plugins/sandisk/sandisk-utils.c +++ b/plugins/sandisk/sandisk-utils.c @@ -552,6 +552,7 @@ __u64 sndk_get_drive_capabilities(struct nvme_global_ctx *ctx, SNDK_DRIVE_CAP_OCP_C5_LOG_PAGE | SNDK_DRIVE_CAP_UDUI | SNDK_DRIVE_CAP_VU_FID_CLEAR_PCIE | + SNDK_DRIVE_CAP_CLEAR_ASSERT | SNDK_DRIVE_CAP_CLOUD_SSD_VERSION | SNDK_DRIVE_CAP_LOG_PAGE_DIR | SNDK_DRIVE_CAP_DRIVE_STATUS | @@ -613,6 +614,7 @@ __u64 sndk_get_drive_capabilities(struct nvme_global_ctx *ctx, SNDK_DRIVE_CAP_OCP_C5_LOG_PAGE | SNDK_DRIVE_CAP_UDUI | SNDK_DRIVE_CAP_VU_FID_CLEAR_PCIE | + SNDK_DRIVE_CAP_CLEAR_ASSERT | SNDK_DRIVE_CAP_CLOUD_SSD_VERSION | SNDK_DRIVE_CAP_LOG_PAGE_DIR | SNDK_DRIVE_CAP_DRIVE_STATUS | diff --git a/plugins/wdc/wdc-nvme.c b/plugins/wdc/wdc-nvme.c index bbccb470f0..2ac07b8b09 100644 --- a/plugins/wdc/wdc-nvme.c +++ b/plugins/wdc/wdc-nvme.c @@ -1962,6 +1962,7 @@ static __u64 wdc_get_drive_capabilities(struct nvme_global_ctx *ctx, struct nvme WDC_DRIVE_CAP_OCP_C5_LOG_PAGE | WDC_DRIVE_CAP_UDUI | WDC_DRIVE_CAP_VU_FID_CLEAR_PCIE | + WDC_DRIVE_CAP_CLEAR_ASSERT | WDC_DRIVE_CAP_CLOUD_SSD_VERSION | WDC_DRIVE_CAP_LOG_PAGE_DIR | WDC_DRIVE_CAP_DRIVE_STATUS | From 37c39e089398fb797ae8f1d4eb6167593ccfe097 Mon Sep 17 00:00:00 2001 From: jeff-lien-sndk Date: Mon, 2 Feb 2026 15:53:13 -0600 Subject: [PATCH 3/3] sndk: vs-internal-log command fixes and enhancements The data-area parameter was being overwritten and set to the default data area value for all cases. This change will only set it when it's not specified. This set of changes fully deprecates a few of the optional parameters for this command across both WDC and Sandisk plugins, and tidies up some of the logic around how telemetry or vendor defined debug is returned. This adds a new --type value in the vs-internal-log command for capturing Host-initiated and Controller-initated telemetry in one command. Signed-off-by: Brandon Paupore Fixes a compile warning on tar file creation. Fixes error that creates an empty file. Signed-off-by: jeff-lien-sndk --- Documentation/nvme-sndk-vs-internal-log.txt | 41 +++-- Documentation/nvme-wdc-vs-internal-log.txt | 34 ++-- plugins/sandisk/sandisk-nvme.c | 178 +++++++++++++++----- plugins/sandisk/sandisk-utils.c | 4 +- plugins/sandisk/sandisk-utils.h | 2 +- plugins/wdc/wdc-nvme.c | 25 ++- 6 files changed, 199 insertions(+), 85 deletions(-) diff --git a/Documentation/nvme-sndk-vs-internal-log.txt b/Documentation/nvme-sndk-vs-internal-log.txt index 7a9e2376a6..c37f679449 100644 --- a/Documentation/nvme-sndk-vs-internal-log.txt +++ b/Documentation/nvme-sndk-vs-internal-log.txt @@ -40,12 +40,25 @@ OPTIONS -d :: --data-area=:: Data area to retrieve. For capture with a --type value that includes - telemetry (CONTROLLER or HOST), this specifies the NVMe telemetry data - area to capture, containing data from areas 1 to . For - capture without such a --type value, this specifies the amount of - vendor defined debug data to capture, and this is only supported on the - SN340, SN350, SN530, SN570, SN730, SN740, SN840, SN850X, SN5000, - SN5100S, SN7000S, SN7100, and SN7150 devices. + telemetry (CONTROLLER, HOST, or BOTH), this specifies the NVMe + telemetry data area to capture, containing data from areas 1 to + . For capture without such a --type value, this specifies + the amount of vendor defined debug data to capture, and this is only + supported on the SN340, SN350, SN530, SN570, SN730, SN740, SN840, + SN850X, SN5000, SN5100S, SN7000S, SN7100, and SN7150 devices. + +-t :: +--type=:: + Specifies the telemetry type - NONE, HOST, CONTROLLER, or BOTH. This + parameter is used to get either the host-initiated or controller- + initiated telemetry log page. If BOTH is specified, both host and + controller telemetry are captured and packaged into a tar archive. + If not specified or if is NONE, the command will return vendor + defined debug data. + +-v :: +--verbose=:: + Provides additional debug messages for certain drives. -f :: --file-size=:: @@ -64,17 +77,6 @@ OPTIONS --data-area parameter, and only for capture with --type=NONE or --type not specified. --t :: ---type=:: - Specifies the telemetry type - NONE, HOST, or CONTROLLER. This parameter - is used to get either the host-initiated or controller-initiated - telemetry log page. If not specified or if is NONE, the command - will return vendor defined debug data. - --v :: ---verbose=:: - Provides additional debug messages for certain drives. - EXAMPLES -------- * Gets the internal firmware log from the device and saves to default file in current directory (e.g. STM00019F3F9_internal_fw_log_20171127_095704.bin): @@ -119,6 +121,11 @@ EXAMPLES ------------ # nvme sndk vs-internal-log /dev/nvme1 -t controller -o ctlr-telem-log-da3.bin -d 3 ------------ +* Gets both host and controller telemetry log pages to data area 3 from the device and packages them in a tar file: ++ +------------ +# nvme sndk vs-internal-log /dev/nvme1 -t both -o both-telem-log-da3.tar -d 3 +------------ NVME ---- diff --git a/Documentation/nvme-wdc-vs-internal-log.txt b/Documentation/nvme-wdc-vs-internal-log.txt index c8a1723a31..414a482aa7 100644 --- a/Documentation/nvme-wdc-vs-internal-log.txt +++ b/Documentation/nvme-wdc-vs-internal-log.txt @@ -47,23 +47,6 @@ OPTIONS SN340, SN350, SN530, SN570, SN730, SN740, SN840, SN850X, SN5000, SN5100S, SN7000S, SN7100, and SN7150 devices. --f :: ---file-size=:: - Specifies the desired size of the data file starting at the passed in - offset. This allows the user to retrieve the data in several smaller - files of the passed in size. This parameter is only supported on the - devices mentioned in the documentation of the --data-area parameter, - and only for capture with --type=NONE or --type not specified. - --e :: ---offset=:: - Specifies the data offset at which to start retrieving the data. This - parameter is used in combination with the file size parameter to - retrieve the data in several smaller files. This parameter is only - supported on the devices mentioned in the documentation of the - --data-area parameter, and only for capture with --type=NONE or --type - not specified. - -t :: --type=:: Specifies the telemetry type - NONE, HOST, or CONTROLLER. This parameter @@ -75,6 +58,23 @@ OPTIONS --verbose=:: Provides additional debug messages for certain drives. +-f :: +--file-size=:: + Deprecated. Specifies the desired size of the data file starting at the + passed in offset. This allows the user to retrieve the data in several + smaller files of the passed in size. This parameter is only supported on + the devices mentioned in the documentation of the --data-area parameter, + and only for capture with --type=NONE or --type not specified. + +-e :: +--offset=:: + Deprecated. Specifies the data offset at which to start retrieving the + data. This parameter is used in combination with the file size parameter + to retrieve the data in several smaller files. This parameter is only + supported on the devices mentioned in the documentation of the + --data-area parameter, and only for capture with --type=NONE or --type + not specified. + EXAMPLES -------- * Gets the internal firmware log from the device and saves to default file in current directory (e.g. STM00019F3F9_internal_fw_log_20171127_095704.bin): diff --git a/plugins/sandisk/sandisk-nvme.c b/plugins/sandisk/sandisk-nvme.c index 76dd84d901..ff9b1d2691 100644 --- a/plugins/sandisk/sandisk-nvme.c +++ b/plugins/sandisk/sandisk-nvme.c @@ -91,6 +91,11 @@ static int sndk_do_cap_telemetry_log(struct nvme_global_ctx *ctx, } host_gen = 0; ctrl_init = 1; + } else if (type == SNDK_TELEMETRY_TYPE_BOTH) { + fprintf(stderr, + "%s: BOTH type should be handled by sndk_do_cap_both_telemetry_log\n", + __func__); + return -EINVAL; } else { fprintf(stderr, "%s: Invalid type parameter; type = %d\n", __func__, type); return -EINVAL; @@ -173,6 +178,81 @@ static int sndk_do_cap_telemetry_log(struct nvme_global_ctx *ctx, return err; } +static int sndk_do_cap_both_telemetry_log(struct nvme_global_ctx *ctx, + struct nvme_transport_handle *hdl, + const char *tar_file, __u32 bs, + int data_area) +{ + char host_file[PATH_MAX] = {0}; + char controller_file[PATH_MAX] = {0}; + char tar_cmd[PATH_MAX * 3] = {0}; + char *base_name; + int ret = 0; + + base_name = strdup(tar_file); + if (!base_name) { + fprintf(stderr, "%s: Memory allocation failed\n", __func__); + return -ENOMEM; + } + + /* Remove .tar extension if present */ + char *tar_ext = strstr(base_name, ".tar"); + + if (tar_ext) + *tar_ext = '\0'; + + /* Create temporary files for host and controller telemetry */ + snprintf(host_file, PATH_MAX, "%s_host_telemetry.bin", base_name); + snprintf(controller_file, PATH_MAX, "%s_controller_telemetry.bin", + base_name); + + fprintf(stderr, "%s: Capturing HOST telemetry to %s\n", __func__, + host_file); + ret = sndk_do_cap_telemetry_log(ctx, hdl, host_file, bs, + SNDK_TELEMETRY_TYPE_HOST, data_area); + if (ret) { + fprintf(stderr, "%s: Failed to capture HOST telemetry: %d\n", + __func__, ret); + goto cleanup; + } + + fprintf(stderr, "%s: Capturing CONTROLLER telemetry to %s\n", __func__, + controller_file); + ret = sndk_do_cap_telemetry_log(ctx, hdl, controller_file, bs, + SNDK_TELEMETRY_TYPE_CONTROLLER, + data_area); + if (ret) { + fprintf(stderr, + "%s: Failed to capture CONTROLLER telemetry: %d\n", + __func__, ret); + goto cleanup_host; + } + + /* Create tar file containing both telemetry files */ + fprintf(stderr, "%s: Creating tar file %s\n", __func__, tar_file); + snprintf(tar_cmd, sizeof(tar_cmd), "tar -cf \"%s\" \"%s\" \"%s\"", + tar_file, host_file, controller_file); + + ret = system(tar_cmd); + if (ret) { + fprintf(stderr, "%s: Failed to create tar file: %s\n", + __func__, tar_file); + ret = -1; + } else { + fprintf(stderr, "%s: Successfully created tar file: %s\n", + __func__, tar_file); + ret = 0; + } + + /* Clean up temporary files */ + unlink(controller_file); +cleanup_host: + unlink(host_file); +cleanup: + free(base_name); + return ret; +} + static __u32 sndk_dump_udui_data(struct nvme_transport_handle *hdl, __u32 dataLen, __u32 offset, __u8 *dump_data) { @@ -196,8 +276,7 @@ static __u32 sndk_dump_udui_data(struct nvme_transport_handle *hdl, } static int sndk_do_cap_udui(struct nvme_transport_handle *hdl, char *file, - __u32 xfer_size, int verbose, __u64 file_size, - __u64 offset) + __u32 xfer_size, int verbose) { int ret = 0; int output; @@ -206,6 +285,7 @@ static int sndk_do_cap_udui(struct nvme_transport_handle *hdl, char *file, __u32 udui_log_hdr_size = sizeof(struct nvme_telemetry_log); __u32 chunk_size = xfer_size; __u64 total_size; + __u64 offset = 0; log = (struct nvme_telemetry_log *)malloc(udui_log_hdr_size); if (!log) { @@ -225,14 +305,6 @@ static int sndk_do_cap_udui(struct nvme_transport_handle *hdl, char *file, } total_size = (le32_to_cpu(log->dalb4) + 1) * 512; - if (offset > total_size) { - fprintf(stderr, "%s: ERROR: SNDK: offset larger than log length = 0x%"PRIx64"\n", - __func__, (uint64_t)total_size); - goto out; - } - - if (file_size && (total_size - offset) > file_size) - total_size = offset + file_size; log = (struct nvme_telemetry_log *)realloc(log, chunk_size); @@ -311,16 +383,18 @@ static int sndk_vs_internal_fw_log(int argc, char **argv, const char *size = "Data retrieval transfer size."; const char *data_area = "Data area to retrieve up to. Supported for telemetry, see man page for other use cases."; + const char *type = + "Telemetry type - NONE, HOST, CONTROLLER, or BOTH:\n" \ + " NONE - Default, capture without using NVMe telemetry.\n" \ + " HOST - Host-initiated telemetry.\n" \ + " CONTROLLER - Controller-initiated telemetry.\n" \ + " BOTH - Both HOST and CONTROLLER telemetry packaged in tar file."; + const char *verbose = "Display more debug messages."; const char *file_size = "Output file size. Deprecated, see man page for supported devices."; const char *offset = "Output file data offset. Deprecated, see man page for supported devices."; - const char *type = - "Telemetry type - NONE, HOST, or CONTROLLER:\n" \ - " NONE - Default, capture without using NVMe telemetry.\n" \ - " HOST - Host-initiated telemetry.\n" \ - " CONTROLLER - Controller-initiated telemetry."; - char f[PATH_MAX] = {0}; + char f[PATH_MAX-4] = {0}; char fileSuffix[PATH_MAX] = {0}; __u32 xfer_size = 0; int telemetry_type = 0, telemetry_data_area = 0; @@ -339,6 +413,7 @@ static int sndk_vs_internal_fw_log(int argc, char **argv, __u64 file_size; __u64 offset; char *type; + bool verbose; }; struct config cfg = { @@ -348,15 +423,18 @@ static int sndk_vs_internal_fw_log(int argc, char **argv, .file_size = 0, .offset = 0, .type = NULL, + .verbose = false, }; NVME_ARGS(opts, OPT_FILE("output-file", 'o', &cfg.file, file), OPT_UINT("transfer-size", 's', &cfg.xfer_size, size), OPT_UINT("data-area", 'd', &cfg.data_area, data_area), + OPT_FILE("type", 't', &cfg.type, type), + OPT_FLAG("verbose", 'v', &cfg.verbose, verbose), OPT_LONG("file-size", 'f', &cfg.file_size, file_size), OPT_LONG("offset", 'e', &cfg.offset, offset), - OPT_FILE("type", 't', &cfg.type, type)); + OPT_END()); ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (ret) @@ -385,7 +463,8 @@ static int sndk_vs_internal_fw_log(int argc, char **argv, goto out; } close(verify_file); - strncpy(f, cfg.file, PATH_MAX - 1); + remove(cfg.file); + strncpy(f, cfg.file, PATH_MAX - 5); } else { sndk_UtilsGetTime(&timeInfo); memset(timeStamp, 0, sizeof(timeStamp)); @@ -423,54 +502,69 @@ static int sndk_vs_internal_fw_log(int argc, char **argv, if (!cfg.type || !strcmp(cfg.type, "NONE") || !strcmp(cfg.type, "none")) { telemetry_type = SNDK_TELEMETRY_TYPE_NONE; - data_area = 0; + telemetry_data_area = 0; } else if (!strcmp(cfg.type, "HOST") || !strcmp(cfg.type, "host")) { telemetry_type = SNDK_TELEMETRY_TYPE_HOST; telemetry_data_area = cfg.data_area; } else if (!strcmp(cfg.type, "CONTROLLER") || !strcmp(cfg.type, "controller")) { telemetry_type = SNDK_TELEMETRY_TYPE_CONTROLLER; telemetry_data_area = cfg.data_area; + } else if (!strcmp(cfg.type, "BOTH") || !strcmp(cfg.type, "both")) { + telemetry_type = SNDK_TELEMETRY_TYPE_BOTH; + telemetry_data_area = cfg.data_area; } else { fprintf(stderr, - "ERROR: SNDK: Invalid type - Must be NONE, HOST or CONTROLLER\n"); + "ERROR: SNDK: Invalid type - Must be NONE, HOST, CONTROLLER, or BOTH\n"); ret = -1; goto out; } capabilities = sndk_get_drive_capabilities(ctx, hdl); - /* Supported through WDC plugin for non-telemetry */ - if ((capabilities & SNDK_DRIVE_CAP_INTERNAL_LOG) && + if ((capabilities & SNDK_DRIVE_CAP_INTERNAL_LOG_MASK) && (telemetry_type != SNDK_TELEMETRY_TYPE_NONE)) { - if (sndk_get_default_telemetry_da(hdl, &telemetry_data_area)) { - fprintf(stderr, "%s: Error determining default telemetry data area\n", - __func__); - return -EINVAL; - } - - ret = sndk_do_cap_telemetry_log(ctx, hdl, f, xfer_size, - telemetry_type, telemetry_data_area); - goto out; - } - - if (capabilities & SNDK_DRIVE_CAP_UDUI) { - if ((telemetry_type == SNDK_TELEMETRY_TYPE_HOST) || - (telemetry_type == SNDK_TELEMETRY_TYPE_CONTROLLER)) { + /* If no data area specified, get the default value */ + if (telemetry_data_area == 0) { if (sndk_get_default_telemetry_da(hdl, &telemetry_data_area)) { fprintf(stderr, "%s: Error determining default telemetry data area\n", - __func__); + __func__); return -EINVAL; } + } + + if (telemetry_type == SNDK_TELEMETRY_TYPE_BOTH) { + /* For BOTH type, ensure filename has .tar extension */ + char tar_file[PATH_MAX] = {0}; + + if (strstr(f, ".tar") == NULL) { + char *bin_ext = strstr(f, ".bin"); + + if (bin_ext) + *bin_ext = '\0'; + snprintf(tar_file, PATH_MAX, "%s.tar", f); + } else { + snprintf(tar_file, PATH_MAX, "%s", f); + } + ret = sndk_do_cap_both_telemetry_log(ctx, hdl, + tar_file, xfer_size, + telemetry_data_area); + } else { ret = sndk_do_cap_telemetry_log(ctx, hdl, f, xfer_size, telemetry_type, telemetry_data_area); - goto out; - } else { - ret = sndk_do_cap_udui(hdl, f, xfer_size, - nvme_args.verbose, cfg.file_size, - cfg.offset); + } + goto out; + } + + if (capabilities & SNDK_DRIVE_CAP_UDUI) { + if (cfg.data_area) { + fprintf(stderr, + "ERROR: SNDK: Data area parameter is not supported when type is NONE\n"); + ret = -1; goto out; } + ret = sndk_do_cap_udui(hdl, f, xfer_size, cfg.verbose); + goto out; } /* Fallback to WDC plugin if otherwise not supported */ diff --git a/plugins/sandisk/sandisk-utils.c b/plugins/sandisk/sandisk-utils.c index 674b0934a8..d77615572e 100644 --- a/plugins/sandisk/sandisk-utils.c +++ b/plugins/sandisk/sandisk-utils.c @@ -26,8 +26,8 @@ static const __u8 WDC_UUID[NVME_UUID_LEN] = { /* WDC_UUID value for SN640_3 devices and SN655 devices */ static const __u8 WDC_UUID_SN640_3[NVME_UUID_LEN] = { - 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, - 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 + 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22 }; /* Sandisk UUID value */ diff --git a/plugins/sandisk/sandisk-utils.h b/plugins/sandisk/sandisk-utils.h index ca70d45955..9a23bd3408 100644 --- a/plugins/sandisk/sandisk-utils.h +++ b/plugins/sandisk/sandisk-utils.h @@ -232,7 +232,7 @@ #define SNDK_TELEMETRY_TYPE_NONE 0x0 #define SNDK_TELEMETRY_TYPE_HOST 0x1 #define SNDK_TELEMETRY_TYPE_CONTROLLER 0x2 - +#define SNDK_TELEMETRY_TYPE_BOTH 0x3 /* Misc */ #define SNDK_MAX_PATH_LEN 256 #define SNDK_GUID_LENGTH 16 diff --git a/plugins/wdc/wdc-nvme.c b/plugins/wdc/wdc-nvme.c index 2ac07b8b09..0c3f85784f 100644 --- a/plugins/wdc/wdc-nvme.c +++ b/plugins/wdc/wdc-nvme.c @@ -3397,6 +3397,13 @@ static int wdc_do_cap_diag(struct nvme_global_ctx *ctx, struct nvme_transport_ha memset(log_hdr, 0, e6_log_hdr_size); if (type == WDC_TELEMETRY_TYPE_NONE) { + if (data_area) { + fprintf(stderr, + "%s: ERROR: Data area parameter is not supported when type is NONE\n", + __func__); + ret = -1; + goto out; + } ret = wdc_dump_length_e6(hdl, WDC_NVME_CAP_DIAG_OPCODE, WDC_NVME_CAP_DIAG_HEADER_TOC_SIZE>>2, @@ -4296,15 +4303,16 @@ static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *acmd, const char *size = "Data retrieval transfer size."; const char *data_area = "Data area to retrieve up to. Supported for telemetry, see man page for other use cases."; - const char *file_size = - "Output file size. See man page for supported devices."; - const char *offset = - "Output file data offset. See man page for supported devices."; const char *type = "Telemetry type - NONE, HOST, or CONTROLLER:\n" \ " NONE - Default, capture without using NVMe telemetry.\n" \ " HOST - Host-initiated telemetry.\n" \ " CONTROLLER - Controller-initiated telemetry."; + const char *verbose = "Display more debug messages."; + const char *file_size = + "Output file size. Deprecated, see man page for supported devices."; + const char *offset = + "Output file data offset. Deprecated, see man page for supported devices."; char f[PATH_MAX] = {0}; char fb[PATH_MAX/2] = {0}; char fileSuffix[PATH_MAX] = {0}; @@ -4327,6 +4335,7 @@ static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *acmd, __u64 file_size; __u64 offset; char *type; + bool verbose; }; struct config cfg = { @@ -4336,15 +4345,18 @@ static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *acmd, .file_size = 0, .offset = 0, .type = NULL, + .verbose = false, }; NVME_ARGS(opts, OPT_FILE("output-file", 'o', &cfg.file, file), OPT_UINT("transfer-size", 's', &cfg.xfer_size, size), OPT_UINT("data-area", 'd', &cfg.data_area, data_area), + OPT_FILE("type", 't', &cfg.type, type), + OPT_FLAG("verbose", 'v', &cfg.verbose, verbose), OPT_LONG("file-size", 'f', &cfg.file_size, file_size), OPT_LONG("offset", 'e', &cfg.offset, offset), - OPT_FILE("type", 't', &cfg.type, type)); + OPT_END()); ret = parse_and_open(&ctx, &hdl, argc, argv, desc, opts); if (ret) @@ -4469,7 +4481,8 @@ static int wdc_vs_internal_fw_log(int argc, char **argv, struct command *acmd, capabilities = wdc_get_drive_capabilities(ctx, hdl); if ((capabilities & WDC_DRIVE_CAP_INTERNAL_LOG) == WDC_DRIVE_CAP_INTERNAL_LOG) { if (!wdc_is_sn861(device_id)) { - if (wdc_get_default_telemetry_da(hdl, &telemetry_data_area)) { + if (telemetry_type != WDC_TELEMETRY_TYPE_NONE && + wdc_get_default_telemetry_da(hdl, &telemetry_data_area)) { fprintf(stderr, "%s: Error determining default telemetry data area\n", __func__); return -EINVAL;