#include <err.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/sysmacros.h>
#include "nvme_ioctl_util.h"
typedef struct {
const char *lt_desc;
uint32_t lt_lid;
size_t lt_len;
} log_test_t;
static const log_test_t basic_log_tests[] = {
{ "Health/SMART log page", NVME_LOGPAGE_HEALTH, 512 },
{ "Firmware log page", NVME_LOGPAGE_FWSLOT, 512 },
};
static bool
basic_get_one_log(int fd, const log_test_t *test)
{
bool ret = true;
nvme_ioctl_get_logpage_t log;
void *data;
if ((data = calloc(test->lt_len, 1)) == NULL) {
err(EXIT_FAILURE, "%s: failed to allocate %zu bytes for "
"log page data", test->lt_desc, test->lt_len);
}
(void) memset(&log, 0, sizeof (log));
log.nigl_csi = NVME_CSI_NVM;
log.nigl_lid = test->lt_lid;
log.nigl_len = test->lt_len;
log.nigl_data = (uintptr_t)data;
if (ioctl(fd, NVME_IOC_GET_LOGPAGE, &log) != 0) {
warn("TEST FAILED: %s: failed to issue get log page ioctl",
test->lt_desc);
ret = false;
} else if (log.nigl_common.nioc_drv_err != NVME_IOCTL_E_OK) {
warnx("TEST FAILED: %s: get log page ioctl set error to 0x%x, "
"but expected success", test->lt_desc,
log.nigl_common.nioc_drv_err);
ret = false;
} else {
uint32_t t;
(void) printf("TEST PASSED: %s: successfully issued get log "
"page command\n", test->lt_desc);
(void) memcpy(&t, data, sizeof (t));
if (t == 0 || t == UINT32_MAX) {
warnx("TEST FAILED: %s: uint32_t at word 0 looks like "
"invalid data, found 0x%x", test->lt_desc, t);
ret = false;
} else {
(void) printf("TEST PASSED: %s: returned data passes "
"initial scrutiny\n", test->lt_desc);
}
}
free(data);
return (ret);
}
int
main(void)
{
int ret = EXIT_SUCCESS;
int fd = nvme_ioctl_test_get_fd(0);
for (size_t i = 0; i < ARRAY_SIZE(basic_log_tests); i++) {
if (!basic_get_one_log(fd, &basic_log_tests[i])) {
ret = EXIT_FAILURE;
}
}
VERIFY0(close(fd));
return (ret);
}