#include <err.h>
#include <stdio.h>
#include "nvme_unit.h"
static const nvme_identify_ctrl_t nvme_ctrl_base = {
.id_oacs = {
.oa_firmware = 1,
.oa_format = 1
},
.id_nn = 1,
.id_frmw = {
.fw_nslot = 1
},
.id_elpe = 3
};
const nvme_valid_ctrl_data_t nvme_ctrl_base_1v0 = {
.vcd_vers = &nvme_vers_1v0,
.vcd_id = &nvme_ctrl_base
};
const nvme_valid_ctrl_data_t nvme_ctrl_base_1v1 = {
.vcd_vers = &nvme_vers_1v1,
.vcd_id = &nvme_ctrl_base
};
const nvme_valid_ctrl_data_t nvme_ctrl_base_1v2 = {
.vcd_vers = &nvme_vers_1v2,
.vcd_id = &nvme_ctrl_base
};
const nvme_valid_ctrl_data_t nvme_ctrl_base_2v0 = {
.vcd_vers = &nvme_vers_2v0,
.vcd_id = &nvme_ctrl_base
};
static const nvme_identify_ctrl_t nvme_ctrl_base_health = {
.id_oacs = {
.oa_firmware = 1,
.oa_format = 1
},
.id_lpa = {
.lp_smart = 1
},
.id_nn = 1,
.id_frmw = {
.fw_nslot = 1
},
.id_elpe = 3
};
const nvme_valid_ctrl_data_t nvme_ctrl_health_1v0 = {
.vcd_vers = &nvme_vers_1v0,
.vcd_id = &nvme_ctrl_base_health
};
static const nvme_identify_ctrl_t nvme_ctrl_fancy = {
.id_oacs = {
.oa_firmware = 1,
.oa_format = 1,
.oa_nsmgmt = 1
},
.id_oncs = {
.on_save = 1,
},
.id_vwc = {
.vwc_present = 1
},
.id_apsta = {
.ap_sup = 1
},
.id_nn = 128,
.id_frmw = {
.fw_nslot = 1
},
.id_lpa = {
.lp_extsup = 1,
.lp_smart = 1,
.lp_cmdeff = 1,
.lp_persist = 1
},
.id_oaes = {
.oaes_nsan = 1
}
};
const nvme_valid_ctrl_data_t nvme_ctrl_ns_1v2 = {
.vcd_vers = &nvme_vers_1v2,
.vcd_id = &nvme_ctrl_fancy
};
const nvme_valid_ctrl_data_t nvme_ctrl_ns_1v3 = {
.vcd_vers = &nvme_vers_1v3,
.vcd_id = &nvme_ctrl_fancy
};
const nvme_valid_ctrl_data_t nvme_ctrl_ns_1v4 = {
.vcd_vers = &nvme_vers_1v4,
.vcd_id = &nvme_ctrl_fancy
};
const nvme_valid_ctrl_data_t nvme_ctrl_ns_2v0 = {
.vcd_vers = &nvme_vers_2v0,
.vcd_id = &nvme_ctrl_fancy
};
static const nvme_identify_ctrl_t nvme_ctrl_nolpa = {
.id_oacs = {
.oa_firmware = 1,
.oa_format = 1,
.oa_nsmgmt = 1
},
.id_oncs = {
.on_save = 1,
},
.id_vwc = {
.vwc_present = 1
},
.id_apsta = {
.ap_sup = 1
},
.id_nn = 128,
.id_frmw = {
.fw_nslot = 1
},
.id_oaes = {
.oaes_nsan = 1
}
};
const nvme_valid_ctrl_data_t nvme_ctrl_nolpa_1v4 = {
.vcd_vers = &nvme_vers_1v4,
.vcd_id = &nvme_ctrl_nolpa
};
static const nvme_identify_ctrl_t nvme_ctrl_nons = {
.id_oacs = {
.oa_firmware = 1,
.oa_format = 1,
},
.id_oncs = {
.on_save = 1,
},
.id_vwc = {
.vwc_present = 1
},
.id_apsta = {
.ap_sup = 1
},
.id_nn = 1,
.id_frmw = {
.fw_nslot = 1
},
.id_lpa = {
.lp_extsup = 1,
.lp_smart = 1,
.lp_cmdeff = 1,
.lp_persist = 1
},
.id_oaes = {
.oaes_nsan = 1
}
};
const nvme_valid_ctrl_data_t nvme_ctrl_nons_1v3 = {
.vcd_vers = &nvme_vers_1v3,
.vcd_id = &nvme_ctrl_nons
};
const nvme_valid_ctrl_data_t nvme_ctrl_nons_1v4 = {
.vcd_vers = &nvme_vers_1v4,
.vcd_id = &nvme_ctrl_nons
};
const nvme_valid_ctrl_data_t nvme_ctrl_nons_2v0 = {
.vcd_vers = &nvme_vers_2v0,
.vcd_id = &nvme_ctrl_nons
};
static const nvme_identify_ctrl_t nvme_ctrl_nocmds = {
.id_nn = 1,
.id_frmw = {
.fw_nslot = 1
},
};
const nvme_valid_ctrl_data_t nvme_ctrl_nocmds_1v0 = {
.vcd_vers = &nvme_vers_1v0,
.vcd_id = &nvme_ctrl_nocmds
};
static const nvme_identify_ctrl_t nvme_ctrl_nogran = {
.id_oacs = {
.oa_firmware = 1,
.oa_format = 1,
},
.id_oncs = {
.on_save = 1
},
.id_frmw = {
.fw_nslot = 3
},
.id_nn = 1,
.ap_fwug = 0xff
};
static const nvme_identify_ctrl_t nvme_ctrl_8kgran = {
.id_oacs = {
.oa_firmware = 1,
.oa_format = 1,
},
.id_oncs = {
.on_save = 1
},
.id_frmw = {
.fw_nslot = 7
},
.id_nn = 1,
.ap_fwug = 0x2
};
const nvme_valid_ctrl_data_t nvme_ctrl_nogran_1v3 = {
.vcd_vers = &nvme_vers_1v3,
.vcd_id = &nvme_ctrl_nogran
};
const nvme_valid_ctrl_data_t nvme_ctrl_8kgran_1v3 = {
.vcd_vers = &nvme_vers_1v3,
.vcd_id = &nvme_ctrl_8kgran
};
static const char *
nvme_field_error_to_str(nvme_field_error_t err)
{
switch (err) {
case NVME_FIELD_ERR_OK:
return ("NVME_FIELD_ERR_OK");
case NVME_FIELD_ERR_UNSUP_VERSION:
return ("NVME_FIELD_ERR_UNSUP_VERSION");
case NVME_FIELD_ERR_UNSUP_FIELD:
return ("NVME_FIELD_ERR_UNSUP_FIELD");
case NVME_FIELD_ERR_BAD_VALUE:
return ("NVME_FIELD_ERR_BAD_VALUE");
default:
return ("unknown");
}
}
static bool
nvme_unit_field_test_one(const nvme_unit_field_test_t *test)
{
char buf[128];
const nvme_field_info_t *field;
nvme_field_error_t err;
buf[0] = '\0';
field = &test->nu_fields[test->nu_index];
err = nvme_field_validate(field, test->nu_data, test->nu_value, buf,
sizeof (buf));
if (err != test->nu_ret) {
warnx("TEST FAILED: %s: found wrong return value %s (%u), "
"expected %s (%u)", test->nu_desc,
nvme_field_error_to_str(err), err,
nvme_field_error_to_str(test->nu_ret), test->nu_ret);
return (false);
}
(void) printf("TEST PASSED: %s: got correct return value\n",
test->nu_desc);
if (err != NVME_FIELD_ERR_OK && buf[0] == '\0') {
warnx("TEST FAILED: %s: error buffer was empty", test->nu_desc);
return (false);
} else if (err == NVME_FIELD_ERR_OK && buf[0] != '\0') {
warnx("TEST FAILED: %s: error buffer was not empty",
test->nu_desc);
return (false);
}
(void) printf("TEST PASSED: %s: error buffer properly formed\n",
test->nu_desc);
return (true);
}
bool
nvme_unit_field_test(const nvme_unit_field_test_t *tests, size_t ntests)
{
bool ret = true;
for (size_t i = 0; i < ntests; i++) {
if (!nvme_unit_field_test_one(&tests[i])) {
ret = false;
}
}
return (ret);
}