1 // Copyright 2017 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #pragma once
6
7 #include <stdint.h>
8 #include <stdio.h>
9
10 #include <ddk/driver.h>
11 #include <zircon/compiler.h>
12 #include <zircon/syscalls/log.h>
13
14 __BEGIN_CDECLS
15
16 // Log Flags
17
18 // Error messages should indicate unexpected failures. They
19 // should be terse (preferably one-line) but informative. They
20 // should avoid flooding the log (if an error is likely to happen
21 // repeatedly, rapidly, it should throttle its dprintf()s).
22 // Error messages are always displayed by default.
23 #define DDK_LOG_ERROR ZX_LOG_ERROR
24
25 // Warning messages are for situations that are not errors but
26 // may be indicative of an impending problem. As with errors they
27 // should not be issued repeatedly and rapidly.
28 // Warning messages are always displayed by default.
29 #define DDK_LOG_WARN ZX_LOG_WARN
30
31 // Info messages should provide terse information messages
32 // around driver startup, shutdown or state change. They
33 // should be concise, infrequent, and one-line whenever possible.
34 // Info messages are always displayed by default.
35 #define DDK_LOG_INFO ZX_LOG_INFO
36
37 // Trace messages are intended to provide detailed information
38 // about what a driver is doing (start/end of transaction, etc)
39 // They should aim for terseness, but provide visibility into
40 // driver operation. They are not displayed by default.
41 #define DDK_LOG_TRACE ZX_LOG_TRACE
42
43 // Spew messages are extremely verbose driver state tracing
44 // (possibly including register dumps / full state dumps).
45 // They are not displayed by default.
46 #define DDK_LOG_SPEW ZX_LOG_SPEW
47
48 // Debug1 through Debug4 messages are driver specific, and not
49 // displayed by default. Consult driver source or documentation
50 // to learn if these messages exist for a specific driver and
51 // what they're used for.
52 #define DDK_LOG_DEBUG1 ZX_LOG_DEBUG1
53 #define DDK_LOG_DEBUG2 ZX_LOG_DEBUG2
54 #define DDK_LOG_DEBUG3 ZX_LOG_DEBUG3
55 #define DDK_LOG_DEBUG4 ZX_LOG_DEBUG4
56
57
58 // Local variants of log levels. These levels will flag debug
59 // messages so they do not get sent over the network. They're
60 // useful for network core or driver logging that would otherwise
61 // spiral out of control as it logs about packets about logging...
62 #define DDK_LOG_LERROR (ZX_LOG_ERROR | ZX_LOG_LOCAL)
63 #define DDK_LOG_LWARN (ZX_LOG_WARN | ZX_LOG_LOCAL)
64 #define DDK_LOG_LINFO (ZX_LOG_INFO | ZX_LOG_LOCAL)
65 #define DDK_LOG_LTRACE (ZX_LOG_TRACE | ZX_LOG_LOCAL)
66 #define DDK_LOG_LSPEW (ZX_LOG_SPEW | ZX_LOG_LOCAL)
67 #define DDK_LOG_LDEBUG1 (ZX_LOG_DEBUG1 | ZX_LOG_LOCAL)
68 #define DDK_LOG_LDEBUG2 (ZX_LOG_DEBUG2 | ZX_LOG_LOCAL)
69 #define DDK_LOG_LDEBUG3 (ZX_LOG_DEBUG3 | ZX_LOG_LOCAL)
70 #define DDK_LOG_LDEBUG4 (ZX_LOG_DEBUG4 | ZX_LOG_LOCAL)
71
72 // zxlog_level_enabled_etc(...) is an internal macro which tests to see if a
73 // given log level is currently enabled. Users should not use this macro, they
74 // should use zxlog_level_enabled(...) instead.
75 #define zxlog_level_enabled_etc(flag) \
76 (((flag & ZX_LOG_LEVEL_MASK) & __zircon_driver_rec__.log_flags) != 0)
77
78 // zxlog_level_enabled(...) provides a way for a driver to test to see if a
79 // particular log level is currently enabled. This allows for patterns where a
80 // driver might want to log something at trace or spew level, but the something
81 // that they want to log might involve a computation or for loop which cannot be
82 // embedded into the log macro and therefor disabled without cost.
83 //
84 // Example:
85 // if (zxlog_level_enabled(TRACE)) {
86 // zxlogf(TRACE, "Scatter gather table has %u entries\n", sg_table.count);
87 // for (uint32_t i = 0; i < sg_table.count; ++i) {
88 // zxlogf(TRACE, "[%u] : 0x%08x, %u\n",
89 // i, sg_table.entry[i].base, sg_table.entry[i].base);
90 // }
91 // }
92 #define zxlog_level_enabled(flag) zxlog_level_enabled_etc(DDK_LOG_##flag)
93
94 void driver_printf(uint32_t flags, const char* fmt, ...) __PRINTFLIKE(2, 3);
95
96 // zxlogf() provides a path to the kernel debuglog gated by log level flags
97 //
98 // Example: zxlogf(ERROR, "oh no! ...");
99 //
100 // By default drivers have ERROR, WARN, and INFO debug levels enabled.
101 // The kernel commandline option driver.NAME.log may be used to override
102 // this. NAME is specified via ZIRCON_DRIVER_BEGIN/ZIRCON_DRIVER_END
103 // macros on each driver's definition. Its value is a comma-separated
104 // list of log levels to enable (prefixed with '+') or disable (prefixed
105 // with '-'). The levels are the strings "error", "info", "trace", "spew",
106 // "debug1", "debug2", "debug3", and "debug4", or an integer mask in decimal,
107 // octal, or hex.
108 //
109 // Example driver.floppydisk.log=-info,+trace,+0x10
110 //
111 #define zxlogf(flag, fmt...) \
112 do { \
113 if (zxlog_level_enabled_etc(DDK_LOG_##flag)) { \
114 driver_printf(DDK_LOG_##flag, fmt); \
115 } \
116 } while (0)
117
driver_set_log_flags(uint32_t flags)118 static inline void driver_set_log_flags(uint32_t flags) {
119 __zircon_driver_rec__.log_flags = flags;
120 }
121
driver_get_log_flags(void)122 static inline uint32_t driver_get_log_flags(void) {
123 return __zircon_driver_rec__.log_flags;
124 }
125
126 __END_CDECLS
127