blob: 89b9c1c3b9831dda560de5783d1344fe9c2abdd3 [file] [log] [blame]
// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef DDK_DEBUG_H_
#define DDK_DEBUG_H_
#include <stdint.h>
#include <stdio.h>
#include <ddk/driver.h>
#include <zircon/compiler.h>
#include <zircon/syscalls/log.h>
__BEGIN_CDECLS
// Log Flags
// Error messages should indicate unexpected failures. They
// should be terse (preferably one-line) but informative. They
// should avoid flooding the log (if an error is likely to happen
// repeatedly, rapidly, it should throttle its dprintf()s).
// Error messages are always displayed by default.
#define DDK_LOG_ERROR ZX_LOG_ERROR
// Warning messages are for situations that are not errors but
// may be indicative of an impending problem. As with errors they
// should not be issued repeatedly and rapidly.
// Warning messages are always displayed by default.
#define DDK_LOG_WARN ZX_LOG_WARN
// Info messages should provide terse information messages
// around driver startup, shutdown or state change. They
// should be concise, infrequent, and one-line whenever possible.
// Info messages are always displayed by default.
#define DDK_LOG_INFO ZX_LOG_INFO
// Trace messages are intended to provide detailed information
// about what a driver is doing (start/end of transaction, etc)
// They should aim for terseness, but provide visibility into
// driver operation. They are not displayed by default.
#define DDK_LOG_TRACE ZX_LOG_TRACE
// Spew messages are extremely verbose driver state tracing
// (possibly including register dumps / full state dumps).
// They are not displayed by default.
#define DDK_LOG_SPEW ZX_LOG_SPEW
// Debug1 through Debug4 messages are driver specific, and not
// displayed by default. Consult driver source or documentation
// to learn if these messages exist for a specific driver and
// what they're used for.
#define DDK_LOG_DEBUG1 ZX_LOG_DEBUG1
#define DDK_LOG_DEBUG2 ZX_LOG_DEBUG2
#define DDK_LOG_DEBUG3 ZX_LOG_DEBUG3
#define DDK_LOG_DEBUG4 ZX_LOG_DEBUG4
// Local variants of log levels. These levels will flag debug
// messages so they do not get sent over the network. They're
// useful for network core or driver logging that would otherwise
// spiral out of control as it logs about packets about logging...
#define DDK_LOG_LERROR (ZX_LOG_ERROR | ZX_LOG_LOCAL)
#define DDK_LOG_LWARN (ZX_LOG_WARN | ZX_LOG_LOCAL)
#define DDK_LOG_LINFO (ZX_LOG_INFO | ZX_LOG_LOCAL)
#define DDK_LOG_LTRACE (ZX_LOG_TRACE | ZX_LOG_LOCAL)
#define DDK_LOG_LSPEW (ZX_LOG_SPEW | ZX_LOG_LOCAL)
#define DDK_LOG_LDEBUG1 (ZX_LOG_DEBUG1 | ZX_LOG_LOCAL)
#define DDK_LOG_LDEBUG2 (ZX_LOG_DEBUG2 | ZX_LOG_LOCAL)
#define DDK_LOG_LDEBUG3 (ZX_LOG_DEBUG3 | ZX_LOG_LOCAL)
#define DDK_LOG_LDEBUG4 (ZX_LOG_DEBUG4 | ZX_LOG_LOCAL)
// zxlog_level_enabled_etc(...) is an internal macro which tests to see if a
// given log level is currently enabled. Users should not use this macro, they
// should use zxlog_level_enabled(...) instead.
#define zxlog_level_enabled_etc(flag) \
(((flag & ZX_LOG_LEVEL_MASK) & __zircon_driver_rec__.log_flags) != 0)
// zxlog_level_enabled(...) provides a way for a driver to test to see if a
// particular log level is currently enabled. This allows for patterns where a
// driver might want to log something at trace or spew level, but the something
// that they want to log might involve a computation or for loop which cannot be
// embedded into the log macro and therefor disabled without cost.
//
// Example:
// if (zxlog_level_enabled(TRACE)) {
// zxlogf(TRACE, "Scatter gather table has %u entries\n", sg_table.count);
// for (uint32_t i = 0; i < sg_table.count; ++i) {
// zxlogf(TRACE, "[%u] : 0x%08x, %u\n",
// i, sg_table.entry[i].base, sg_table.entry[i].base);
// }
// }
#define zxlog_level_enabled(flag) zxlog_level_enabled_etc(DDK_LOG_##flag)
void driver_printf(uint32_t flags, const char* fmt, ...) __PRINTFLIKE(2, 3);
// zxlogf() provides a path to the kernel debuglog gated by log level flags
//
// Example: zxlogf(ERROR, "oh no! ...");
//
// By default drivers have ERROR, WARN, and INFO debug levels enabled.
// The kernel commandline option driver.NAME.log may be used to override
// this. NAME is specified via ZIRCON_DRIVER_BEGIN/ZIRCON_DRIVER_END
// macros on each driver's definition. Its value is a comma-separated
// list of log levels to enable (prefixed with '+') or disable (prefixed
// with '-'). The levels are the strings "error", "info", "trace", "spew",
// "debug1", "debug2", "debug3", and "debug4", or an integer mask in decimal,
// octal, or hex.
//
// Example driver.floppydisk.log=-info,+trace,+0x10
//
#define zxlogf(flag, fmt...) \
do { \
if (zxlog_level_enabled_etc(DDK_LOG_##flag)) { \
driver_printf(DDK_LOG_##flag, fmt); \
} \
} while (0)
static inline void driver_set_log_flags(uint32_t flags) {
__zircon_driver_rec__.log_flags = flags;
}
static inline uint32_t driver_get_log_flags(void) {
return __zircon_driver_rec__.log_flags;
}
__END_CDECLS
#endif // DDK_DEBUG_H_