// SPDX-License-Identifier: GPL-2.0-or-later #include #include #include #include #include #include #include #include "logging.h" int log_level; int map_log_level(int verbose, bool quiet) { int log_level; /* * LOG_NOTICE is unused thus the user has to provide two 'v' for getting * any feedback at all. Thus skip this level */ verbose++; switch (verbose) { case 0: log_level = LOG_WARNING; break; case 1: log_level = LOG_NOTICE; break; case 2: log_level = LOG_INFO; break; default: log_level = LOG_DEBUG; break; } if (quiet) log_level = LOG_ERR; return log_level; } static void nvme_show_common(struct nvme_passthru_cmd *cmd) { printf("opcode : %02x\n", cmd->opcode); printf("flags : %02x\n", cmd->flags); printf("rsvd1 : %04x\n", cmd->rsvd1); printf("nsid : %08x\n", cmd->nsid); printf("cdw2 : %08x\n", cmd->cdw2); printf("cdw3 : %08x\n", cmd->cdw3); printf("data_len : %08x\n", cmd->data_len); printf("metadata_len : %08x\n", cmd->metadata_len); printf("addr : %"PRIx64"\n", (uint64_t)(uintptr_t)cmd->addr); printf("metadata : %"PRIx64"\n", (uint64_t)(uintptr_t)cmd->metadata); printf("cdw10 : %08x\n", cmd->cdw10); printf("cdw11 : %08x\n", cmd->cdw11); printf("cdw12 : %08x\n", cmd->cdw12); printf("cdw13 : %08x\n", cmd->cdw13); printf("cdw14 : %08x\n", cmd->cdw14); printf("cdw15 : %08x\n", cmd->cdw15); printf("timeout_ms : %08x\n", cmd->timeout_ms); } static void nvme_show_command(struct nvme_passthru_cmd *cmd, int err) { nvme_show_common(cmd); printf("result : %08x\n", cmd->result); printf("err : %d\n", err); } static void nvme_show_command64(struct nvme_passthru_cmd64 *cmd, int err) { nvme_show_common((struct nvme_passthru_cmd *)cmd); printf("result : %"PRIx64"\n", (uint64_t)(uintptr_t)cmd->result); printf("err : %d\n", err); } static void nvme_show_latency(struct timeval start, struct timeval end) { printf("latency : %lu us\n", (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_usec - start.tv_usec)); } int nvme_submit_passthru(int fd, unsigned long ioctl_cmd, struct nvme_passthru_cmd *cmd, __u32 *result) { struct timeval start; struct timeval end; int err; if (log_level >= LOG_INFO) gettimeofday(&start, NULL); err = ioctl(fd, ioctl_cmd, cmd); if (log_level >= LOG_INFO) { gettimeofday(&end, NULL); if (log_level >= LOG_DEBUG) nvme_show_command(cmd, err); nvme_show_latency(start, end); } if (err >= 0 && result) *result = cmd->result; return err; } int nvme_submit_passthru64(int fd, unsigned long ioctl_cmd, struct nvme_passthru_cmd64 *cmd, __u64 *result) { struct timeval start; struct timeval end; int err; if (log_level >= LOG_INFO) gettimeofday(&start, NULL); err = ioctl(fd, ioctl_cmd, cmd); if (log_level >= LOG_INFO) { gettimeofday(&end, NULL); if (log_level >= LOG_DEBUG) nvme_show_command64(cmd, err); nvme_show_latency(start, end); } if (err >= 0 && result) *result = cmd->result; return err; }