diff options
Diffstat (limited to '')
-rw-r--r-- | util/logging.c | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/util/logging.c b/util/logging.c new file mode 100644 index 0000000..c26d9e2 --- /dev/null +++ b/util/logging.c @@ -0,0 +1,138 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include <inttypes.h> + +#include <stdint.h> +#include <sys/ioctl.h> +#include <sys/syslog.h> +#include <sys/time.h> +#include <linux/types.h> + +#include <libnvme.h> + +#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; +} |