From aac8e75cb41ba7e85125c1b1793916bb920fa6f1 Mon Sep 17 00:00:00 2001 From: jeff-lien-sndk Date: Fri, 25 Jul 2025 14:14:34 -0500 Subject: [PATCH] linux: Add functions to set and clear etdas bit To retrieve telemetry log data area 4, the Extended Telemetry Data Area 4 Supported in the Host Behavior Support feature needs to be set. The bit will be cleared after the log has been retrieved. This commit will add functions to set and clear that bit. Signed-off-by: jeff-lien-sndk [wagi: - added changed argument to clear function - refactored error handling (return early)] Signed-off-by: Daniel Wagner --- src/libnvme.map | 3 +++ src/nvme/linux.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ src/nvme/linux.h | 22 ++++++++++++++++++++++ 3 files changed, 72 insertions(+) diff --git a/src/libnvme.map b/src/libnvme.map index bae5962ce..bf2d5a378 100644 --- a/src/libnvme.map +++ b/src/libnvme.map @@ -1,5 +1,8 @@ # SPDX-License-Identifier: LGPL-2.1-or-later LIBNVME_UNRELEASED { + global: + nvme_set_etdas; + nvme_clear_etdas; }; LIBNVME_1_14 { diff --git a/src/nvme/linux.c b/src/nvme/linux.c index ae4aa526f..cdbb91254 100644 --- a/src/nvme/linux.c +++ b/src/nvme/linux.c @@ -121,6 +121,53 @@ int nvme_fw_download_seq(int fd, __u32 size, __u32 xfer, __u32 offset, return err; } +int nvme_set_etdas(int fd, bool *changed) +{ + struct nvme_feat_host_behavior da4; + int err; + + err = nvme_get_features_host_behavior(fd, 0, &da4, NULL); + if (err) + return err; + + if (da4.etdas) { + *changed = false; + return 0; + } + + da4.etdas = 1; + + err = nvme_set_features_host_behavior(fd, 0, &da4); + if (err) + return err; + + *changed = true; + return 0; +} + +int nvme_clear_etdas(int fd, bool *changed) +{ + struct nvme_feat_host_behavior da4; + int err; + + err = nvme_get_features_host_behavior(fd, 0, &da4, NULL); + if (err) + return err; + + if (!da4.etdas) { + *changed = false; + return 0; + } + + da4.etdas = 0; + err = nvme_set_features_host_behavior(fd, 0, &da4); + if (err) + return err; + + *changed = true; + return 0; +} + int nvme_get_telemetry_max(int fd, enum nvme_telemetry_da *da, size_t *data_tx) { _cleanup_free_ struct nvme_id_ctrl *id_ctrl = NULL; diff --git a/src/nvme/linux.h b/src/nvme/linux.h index e865a8c8a..330fa9fd3 100644 --- a/src/nvme/linux.h +++ b/src/nvme/linux.h @@ -34,6 +34,28 @@ int nvme_fw_download_seq(int fd, __u32 size, __u32 xfer, __u32 offset, void *buf); +/** + * nvme_set_etdas() - Set the Extended Telemetry Data Area 4 Supported bit + * @fd: File descriptor of nvme device + * @changed: boolean to indicate whether or not the host + * behavior support feature had been changed + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_set_etdas(int fd, bool *changed); + +/** + * nvme_clear_etdas() - Clear the Extended Telemetry Data Area 4 Supported bit + * @fd: File descriptor of nvme device + * @changed: boolean to indicate whether or not the host + * behavior support feature had been changed + * + * Return: The nvme command status if a response was received (see + * &enum nvme_status_field) or -1 with errno set otherwise. + */ +int nvme_clear_etdas(int fd, bool *changed); + /** * nvme_get_telemetry_max() - Get telemetry limits * @fd: File descriptor of nvme device