summaryrefslogtreecommitdiffstats
path: root/util
diff options
context:
space:
mode:
Diffstat (limited to 'util')
-rw-r--r--util/logging.c138
-rw-r--r--util/logging.h12
-rw-r--r--util/meson.build1
3 files changed, 151 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;
+}
diff --git a/util/logging.h b/util/logging.h
new file mode 100644
index 0000000..7b1814c
--- /dev/null
+++ b/util/logging.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#ifndef DEBUG_H_
+#define DEBUG_H_
+
+#include <stdbool.h>
+
+extern int log_level;
+
+int map_log_level(int verbose, bool quiet);
+
+#endif // DEBUG_H_
diff --git a/util/meson.build b/util/meson.build
index dfc683b..0065b86 100644
--- a/util/meson.build
+++ b/util/meson.build
@@ -4,6 +4,7 @@ sources += [
'util/argconfig.c',
'util/base64.c',
'util/crc32.c',
+ 'util/logging.c',
'util/mem.c',
'util/suffix.c',
'util/types.c',