While similar, these are logs are not obtained the same way.
Signed-off-by: Keith Busch <kbusch@kernel.org>
void *log;
time_t s;
- ret = nvme_get_telemetry_log(nvme_ctrl_get_fd(c), false, true, 3, &log,
- &log_size);
+ /* Clear the log (rae == false) at the end to see new telemetry events later */
+ ret = nvme_get_ctrl_telemetry(nvme_ctrl_get_fd(c), false, &log, &log_size);
if (ret)
return;
- /* Clear the log (rae == false) to see new telemetry events later */
- nvme_get_log_telemetry_ctrl(nvme_ctrl_get_fd(c), false, 0, sizeof(buf),
- buf);
- memset(buf, 0, sizeof(buf));
-
s = time(NULL);
ret = snprintf(buf, sizeof(buf), "/var/log/%s-telemetry-%ld",
nvme_ctrl_get_subsysnqn(c), s);
};
/**
- * enum -
+ * enum nvme_directive_receive_doper -
+ * @NVME_DIRECTIVE_RECEIVE_IDENTIFY_DOPER_PARAM:
+ * @NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_PARAM:
+ * @NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_STATUS:
+ * @NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_RESOURCE:
*/
-enum nvme_cmd_directive_receive_identify_doper {
+enum nvme_directive_receive_doper {
NVME_DIRECTIVE_RECEIVE_IDENTIFY_DOPER_PARAM = 0x01,
-};
-
-/**
- * enum -
- */
-enum nvme_cmd_directive_receive_streams_doper {
NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_PARAM = 0x01,
NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_STATUS = 0x02,
NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_RESOURCE = 0x03,
};
/**
- * enum -
+ * enum nvme_directive_send_doper -
+ * @NVME_DIRECTIVE_SEND_IDENTIFY_DOPER_ENDIR:
+ * @NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_IDENTIFIER:
+ * @NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_RESOURCE:
*/
-enum nvme_cmd_directive_send_identify_doper {
+enum nvme_directive_send_doper {
NVME_DIRECTIVE_SEND_IDENTIFY_DOPER_ENDIR = 0x01,
+ NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_IDENTIFIER = 0x01,
+ NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_RESOURCE = 0x02,
};
/**
* enum -
*/
-enum nvme_cmd_directive_send_identify_endir {
+enum nvme_directive_send_identify_endir {
NVME_DIRECTIVE_SEND_IDENTIFY_ENDIR_DISABLE = 0,
NVME_DIRECTIVE_SEND_IDENTIFY_ENDIR_ENABLE = 1,
};
-/**
- * enum -
- */
-enum nvme_cmd_directive_send_streams_doper {
- NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_IDENTIFIER = 0x01,
- NVME_DIRECTIVE_SEND_STREAMS_DOPER_RELEASE_RESOURCE = 0x02,
-};
-
/**
* enum nvme_sanitize_sanact -
* @NVME_SANITIZE_SANACT_EXIT_FAILURE:
* @fd: File descriptor of nvme device
* @nsid: Namespace ID, if applicable
* @dspec: Directive specific field
- * @doper: Directive operation
+ * @doper: Directive send operation, see &enum nvme_directive_send_doper
* @dtype: Directive type, see &enum nvme_directive_dtype
* @dw12: Directive specific command dword12
* @data_len: Length of data payload in bytes
* Return: The nvme command status if a response was received or -1 with errno
* set otherwise.
*/
-int nvme_directive_send(int fd, __u32 nsid, __u16 dspec, __u8 doper,
+int nvme_directive_send(int fd, __u32 nsid, __u16 dspec,
+ enum nvme_directive_send_doper doper,
enum nvme_directive_dtype dtype, __u32 cdw12,
__u32 data_len, void *data, __u32 *result);
* @fd: File descriptor of nvme device
* @nsid: Namespace ID, if applicable
* @dspec: Directive specific field
- * @doper: Directive operation
+ * @doper: Directive receive operation, see &enum nvme_directive_receive_doper
* @dtype: Directive type, see &enum nvme_directive_dtype
* @dw12: Directive specific command dword12
* @data_len: Length of data payload
* Return: The nvme command status if a response was received or -1 with errno
* set otherwise.
*/
-int nvme_directive_recv(int fd, __u32 nsid, __u16 dspec, __u8 doper,
+int nvme_directive_recv(int fd, __u32 nsid, __u16 dspec,
+ enum nvme_directive_receive_doper doper,
enum nvme_directive_dtype dtype, __u32 cdw12,
__u32 data_len, void *data, __u32 *result);
return nvme_submit_admin_passthru(fd, &cmd, NULL);
}
-int nvme_directive_send(int fd, __u32 nsid, __u16 dspec, __u8 doper,
+int nvme_directive_send(int fd, __u32 nsid, __u16 dspec,
+ enum nvme_directive_send_doper doper,
enum nvme_directive_dtype dtype, __u32 cdw12,
__u32 data_len, void *data, __u32 *result)
{
NULL);
}
-int nvme_directive_recv(int fd, __u32 nsid, __u16 dspec, __u8 doper,
+int nvme_directive_recv(int fd, __u32 nsid, __u16 dspec,
+ enum nvme_directive_receive_doper doper,
enum nvme_directive_dtype dtype, __u32 cdw12,
__u32 data_len, void *data, __u32 *result)
{
__u32 xfer_len, __u32 data_len, void *data)
{
__u64 offset = 0, xfer;
+ bool retain = true;
void *ptr = data;
int ret;
if (xfer > xfer_len)
xfer = xfer_len;
+ /*
+ * Always retain regardless of the RAE parameter until the very
+ * last portion of this log page so the data remains latched
+ * during the fetch sequence.
+ */
+ if (offset + xfer == data_len)
+ retain = rae;
+
ret = nvme_get_log(fd, log_id, nsid, offset, NVME_LOG_LSP_NONE,
- NVME_LOG_LSI_NONE, rae, NVME_UUID_NONE,
+ NVME_LOG_LSI_NONE, retain, NVME_UUID_NONE,
xfer, ptr);
if (ret)
return ret;
return __nvme_get_log_page(fd, nsid, log_id, rae, 4096, data_len, data);
}
-int nvme_get_telemetry_log(int fd, bool create, bool ctrl, int data_area,
- void **buf, __u32 *log_size)
+static int nvme_get_telemetry_log(int fd, bool create, bool ctrl, bool rae, void **buf,
+ __u32 *log_size)
{
static const __u32 xfer = 512;
- __u8 lid = NVME_LOG_LID_TELEMETRY_HOST;
struct nvme_telemetry_log *telem;
__u32 size;
+ __u8 lid;
void *log;
int err;
if (ctrl) {
err = nvme_get_log_telemetry_ctrl(fd, true, 0, xfer, log);
lid = NVME_LOG_LID_TELEMETRY_CTRL;
- } else if (create)
- err = nvme_get_log_create_telemetry_host(fd, log);
- else
- err = nvme_get_log_telemetry_host(fd, 0, xfer, log);
+ } else {
+ lid = NVME_LOG_LID_TELEMETRY_HOST;
+ if (create)
+ err = nvme_get_log_create_telemetry_host(fd, log);
+ else
+ err = nvme_get_log_telemetry_host(fd, 0, xfer, log);
+ }
if (err)
goto free;
telem = log;
- if (!telem->ctrlavail) {
+ if (ctrl && !telem->ctrlavail) {
size = xfer;
goto done;
}
- switch (data_area) {
- case 1:
- size = (le16_to_cpu(telem->dalb1) * xfer) + xfer;
- break;
- case 2:
- size = (le16_to_cpu(telem->dalb2) * xfer) + xfer;
- break;
- case 3:
- size = (le16_to_cpu(telem->dalb3) * xfer) + xfer;
- break;
- default:
- errno = EINVAL;
- err = -1;
- goto free;
- }
-
+ size = (le16_to_cpu(telem->dalb3) * xfer) + xfer;
log = realloc(log, size);
if (!log) {
errno = ENOMEM;
goto free;
}
- err = nvme_get_log_page(fd, NVME_NSID_NONE, lid, true, size, (void *)log);
+ err = nvme_get_log_page(fd, NVME_NSID_NONE, lid, rae, size, (void *)log);
if (err)
goto free;
done:
return err;
}
+int nvme_get_ctrl_telemetry(int fd, bool rae, void **buf, __u32 *log_size)
+{
+ return nvme_get_telemetry_log(fd, false, true, rae, buf, log_size);
+}
+
+int nvme_get_host_telemetry(int fd, void **buf, __u32 *log_size)
+{
+ return nvme_get_telemetry_log(fd, false, false, false, buf, log_size);
+}
+
+int nvme_get_new_host_telemetry(int fd, void **buf, __u32 *log_size)
+{
+ return nvme_get_telemetry_log(fd, true, false, false, buf, log_size);
+}
+
void nvme_setup_dsm_range(struct nvme_dsm_range *dsm, __u32 *ctx_attrs,
__u32 *llbas, __u64 *slbas, __u16 nr_ranges)
{
return 0;
}
-int nvme_get_directive_receive_length(__u8 dtype, __u8 doper, __u32 *len)
+int nvme_get_directive_receive_length(enum nvme_directive_dtype dtype,
+ enum nvme_directive_receive_doper doper, __u32 *len)
{
switch (dtype) {
case NVME_DIRECTIVE_DTYPE_IDENTIFY:
switch (doper) {
case NVME_DIRECTIVE_RECEIVE_IDENTIFY_DOPER_PARAM:
*len = sizeof(struct nvme_id_directives);
- break;
+ return 0;
default:
errno = EINVAL;
return -1;
}
- break;
case NVME_DIRECTIVE_DTYPE_STREAMS:
switch (doper) {
case NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_PARAM:
*len = sizeof(struct nvme_streams_directive_params);
- break;
+ return 0;
case NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_STATUS:
*len = (128 * 1024) * sizeof(__le16);
- break;
+ return 0;
case NVME_DIRECTIVE_RECEIVE_STREAMS_DOPER_RESOURCE:
*len = 0;
- break;
+ return 0;
default:
return -EINVAL;
}
default:
return -EINVAL;
}
- return 0;
}
static int __nvme_set_attr(const char *path, const char *value)
#include <stdbool.h>
#include <linux/types.h>
-#include "types.h"
+#include "cmd.h"
/**
* nvme_status_to_errno() - Converts nvme return status to errno
void *buf);
/**
- * nvme_get_telemetry_log() -
+ * nvme_get_ctrl_telemetry() -
* @fd:
- * @create:
- * @ctrl:
- * @data_area:
+ * @rae:
* @buf:
* @log_size:
*
- * Return:
+ * Returns:
+ */
+int nvme_get_ctrl_telemetry(int fd, bool rae, void **buf, __u32 *log_size);
+
+/**
+ * nvme_get_host_telemetry() -
+ * @fd:
+ * @buf:
+ * @log_size:
+ *
+ * Returns:
*/
-int nvme_get_telemetry_log(int fd, bool create, bool ctrl, int data_area,
- void **buf, __u32 *log_size);
+int nvme_get_host_telemetry(int fd, void **buf, __u32 *log_size);
+
+/**
+ * nvme_get_new_host_telemetry() -
+ * @fd:
+ * @buf:
+ * @log_size:
+ *
+ * Returns:
+ */
+int nvme_get_new_host_telemetry(int fd, void **buf, __u32 *log_size);
/**
* nvme_setup_id_ns() -
/**
* nvme_get_directive_receive_length() -
- * @dtype:
- * @doper:
- * @len:
+ * @dtype: Directive type, see &enum nvme_directive_dtype
+ * @doper: Directive receive operation, see &enum nvme_directive_receive_doper
+ * @len: Address to save the payload length of the directive in bytes on
+ * a successful decode
*
- * Return:
+ * Return: 0 on success, -1 with errno set to EINVAL.
*/
-int nvme_get_directive_receive_length(__u8 dtype, __u8 doper, __u32 *len);
+int nvme_get_directive_receive_length(enum nvme_directive_dtype dtype,
+ enum nvme_directive_receive_doper doper, __u32 *len);
/**
* nvme_open() - Open an nvme controller or namespace device