return do_admin_op(get_log_device_self_test, dev, log);
}
-int nvme_cli_get_log_create_telemetry_host(struct nvme_dev *dev,
+int nvme_cli_get_log_create_telemetry_host_mcda(struct nvme_dev *dev,
+ enum nvme_telemetry_da mcda,
struct nvme_telemetry_log *log)
{
- return do_admin_op(get_log_create_telemetry_host, dev, log);
+ return do_admin_op(get_log_create_telemetry_host_mcda, dev, mcda, log);
}
int nvme_cli_get_log_telemetry_host(struct nvme_dev *dev, __u64 offset,
{
_cleanup_free_ struct nvme_id_ctrl *id_ctrl = NULL;
- size_t dalb = 0;
+ size_t dalb, da1lb = le16_to_cpu(telem->dalb1), da2lb = le16_to_cpu(telem->dalb2),
+ da3lb = le16_to_cpu(telem->dalb3), da4lb = le32_to_cpu(telem->dalb4);
+ bool data_area_4_support;
id_ctrl = nvme_alloc(sizeof(*id_ctrl));
if (!id_ctrl)
return -ENOMEM;
+ if (nvme_cli_identify_ctrl(dev, id_ctrl)) {
+ perror("identify-ctrl");
+ return -errno;
+ }
+
+ data_area_4_support = id_ctrl->lpa & 0x40;
+
switch (da) {
+ case NVME_TELEMETRY_DA_CTRL_DETERMINE:
+ if (data_area_4_support)
+ dalb = da4lb;
+ else
+ dalb = da3lb;
+ break;
case NVME_TELEMETRY_DA_1:
- dalb = le16_to_cpu(telem->dalb1);
+ dalb = da1lb;
break;
case NVME_TELEMETRY_DA_2:
- dalb = le16_to_cpu(telem->dalb2);
+ dalb = da2lb;
break;
case NVME_TELEMETRY_DA_3:
/* dalb3 >= dalb2 >= dalb1 */
- dalb = le16_to_cpu(telem->dalb3);
+ dalb = da3lb;
break;
case NVME_TELEMETRY_DA_4:
- if (nvme_cli_identify_ctrl(dev, id_ctrl)) {
- perror("identify-ctrl");
- return -errno;
- }
-
- if (id_ctrl->lpa & 0x40) {
- dalb = le32_to_cpu(telem->dalb4);
+ if (data_area_4_support) {
+ dalb = da4lb;
} else {
nvme_show_error(
"Data area 4 unsupported, bit 6 of Log Page Attributes not set");
if (!log)
return -ENOMEM;
- err = nvme_cli_get_log_create_telemetry_host(dev, log);
+ err = nvme_cli_get_log_create_telemetry_host_mcda(dev, da, log);
if (err) {
if (errno)
return -errno;
const char *hgen = "Have the host tell the controller to generate the report";
const char *cgen = "Gather report generated by the controller.";
const char *dgen = "Pick which telemetry data area to report. Default is 3 to fetch areas 1-3. Valid options are 1, 2, 3, 4.";
+ const char *mcda = "Host-init Maximum Created Data Area. Valid options are 0 ~ 4 "
+ "If given, This option will override dgen. 0 : controller determines data area";
_cleanup_free_ struct nvme_telemetry_log *log = NULL;
_cleanup_nvme_dev_ struct nvme_dev *dev = NULL;
bool ctrl_init;
int data_area;
bool rae;
+ __u8 mcda;
};
struct config cfg = {
.file_name = NULL,
.ctrl_init = false,
.data_area = 3,
.rae = false,
+ .mcda = 0xff,
};
NVME_ARGS(opts,
OPT_UINT("host-generate", 'g', &cfg.host_gen, hgen),
OPT_FLAG("controller-init", 'c', &cfg.ctrl_init, cgen),
OPT_UINT("data-area", 'd', &cfg.data_area, dgen),
- OPT_FLAG("rae", 'r', &cfg.rae, rae));
+ OPT_FLAG("rae", 'r', &cfg.rae, rae),
+ OPT_BYTE("mcda", 'm', &cfg.mcda, mcda));
err = parse_and_open(&dev, argc, argv, desc, opts);
if (err)
}
cfg.host_gen = !!cfg.host_gen;
+
+ if (cfg.mcda != 0xff) {
+ if (cfg.ctrl_init || !cfg.host_gen) {
+ nvme_show_error("mcda allowed for Host-init Creation!");
+ return -EINVAL;
+ }
+ cfg.data_area = cfg.mcda;
+ }
+
output = open(cfg.file_name, O_WRONLY | O_CREAT | O_TRUNC, 0666);
if (output < 0) {
nvme_show_error("Failed to open output file %s: %s!",