Release 4.15 drivers/gpu/drm/amd/display/dc/basics/logger.c
  
  
  
/*
 * Copyright 2012-15 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * Authors: AMD
 *
 */
#include "dm_services.h"
#include "include/logger_interface.h"
#include "logger.h"
#define NUM_ELEMENTS(a) (sizeof(a) / sizeof((a)[0]))
static const struct dc_log_type_info log_type_info_tbl[] = {
		{LOG_ERROR,                 "Error"},
		{LOG_WARNING,               "Warning"},
		{LOG_DEBUG,		    "Debug"},
		{LOG_DC,                    "DC_Interface"},
		{LOG_SURFACE,               "Surface"},
		{LOG_HW_HOTPLUG,            "HW_Hotplug"},
		{LOG_HW_LINK_TRAINING,      "HW_LKTN"},
		{LOG_HW_SET_MODE,           "HW_Mode"},
		{LOG_HW_RESUME_S3,          "HW_Resume"},
		{LOG_HW_AUDIO,              "HW_Audio"},
		{LOG_HW_HPD_IRQ,            "HW_HPDIRQ"},
		{LOG_MST,                   "MST"},
		{LOG_SCALER,                "Scaler"},
		{LOG_BIOS,                  "BIOS"},
		{LOG_BANDWIDTH_CALCS,       "BWCalcs"},
		{LOG_BANDWIDTH_VALIDATION,  "BWValidation"},
		{LOG_I2C_AUX,               "I2C_AUX"},
		{LOG_SYNC,                  "Sync"},
		{LOG_BACKLIGHT,             "Backlight"},
		{LOG_FEATURE_OVERRIDE,      "Override"},
		{LOG_DETECTION_EDID_PARSER, "Edid"},
		{LOG_DETECTION_DP_CAPS,     "DP_Caps"},
		{LOG_RESOURCE,              "Resource"},
		{LOG_DML,                   "DML"},
		{LOG_EVENT_MODE_SET,        "Mode"},
		{LOG_EVENT_DETECTION,       "Detect"},
		{LOG_EVENT_LINK_TRAINING,   "LKTN"},
		{LOG_EVENT_LINK_LOSS,       "LinkLoss"},
		{LOG_EVENT_UNDERFLOW,       "Underflow"},
		{LOG_IF_TRACE,              "InterfaceTrace"},
		{LOG_DTN,                   "DTN"}
};
/* ----------- Object init and destruction ----------- */
static bool construct(struct dc_context *ctx, struct dal_logger *logger,
		      uint32_t log_mask)
{
	/* malloc buffer and init offsets */
	logger->log_buffer_size = DAL_LOGGER_BUFFER_MAX_SIZE;
	logger->log_buffer = (char *)kzalloc(logger->log_buffer_size * sizeof(char),
					     GFP_KERNEL);
	if (!logger->log_buffer)
		return false;
	/* Initialize both offsets to start of buffer (empty) */
	logger->buffer_read_offset = 0;
	logger->buffer_write_offset = 0;
	logger->open_count = 0;
	logger->flags.bits.ENABLE_CONSOLE = 1;
	logger->flags.bits.ENABLE_BUFFER = 0;
	logger->ctx = ctx;
	logger->mask = log_mask;
	return true;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Harry Wentland | 112 | 100.00% | 3 | 100.00% | 
| Total | 112 | 100.00% | 3 | 100.00% | 
static void destruct(struct dal_logger *logger)
{
	if (logger->log_buffer) {
		kfree(logger->log_buffer);
		logger->log_buffer = NULL;
	}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Harry Wentland | 32 | 100.00% | 2 | 100.00% | 
| Total | 32 | 100.00% | 2 | 100.00% | 
struct dal_logger *dal_logger_create(struct dc_context *ctx, uint32_t log_mask)
{
	/* malloc struct */
	struct dal_logger *logger = kzalloc(sizeof(struct dal_logger),
					    GFP_KERNEL);
	if (!logger)
		return NULL;
	if (!construct(ctx, logger, log_mask)) {
		kfree(logger);
		return NULL;
	}
	return logger;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Harry Wentland | 65 | 100.00% | 3 | 100.00% | 
| Total | 65 | 100.00% | 3 | 100.00% | 
uint32_t dal_logger_destroy(struct dal_logger **logger)
{
	if (logger == NULL || *logger == NULL)
		return 1;
	destruct(*logger);
	kfree(*logger);
	*logger = NULL;
	return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Harry Wentland | 45 | 100.00% | 2 | 100.00% | 
| Total | 45 | 100.00% | 2 | 100.00% | 
/* ------------------------------------------------------------------------ */
static bool dal_logger_should_log(
	struct dal_logger *logger,
	enum dc_log_type log_type)
{
	if (logger->mask & (1 << log_type))
		return true;
	return false;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Harry Wentland | 33 | 100.00% | 1 | 100.00% | 
| Total | 33 | 100.00% | 1 | 100.00% | 
static void log_to_debug_console(struct log_entry *entry)
{
	struct dal_logger *logger = entry->logger;
	if (logger->flags.bits.ENABLE_CONSOLE == 0)
		return;
	if (entry->buf_offset) {
		switch (entry->type) {
		case LOG_ERROR:
			dm_error("%s", entry->buf);
			break;
		default:
			dm_output_to_console("%s", entry->buf);
			break;
		}
	}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Harry Wentland | 73 | 100.00% | 1 | 100.00% | 
| Total | 73 | 100.00% | 1 | 100.00% | 
/* Print everything unread existing in log_buffer to debug console*/
void dm_logger_flush_buffer(struct dal_logger *logger, bool should_warn)
{
	char *string_start = &logger->log_buffer[logger->buffer_read_offset];
	if (should_warn)
		dm_output_to_console(
			"---------------- FLUSHING LOG BUFFER ----------------\n");
	while (logger->buffer_read_offset < logger->buffer_write_offset) {
		if (logger->log_buffer[logger->buffer_read_offset] == '\0') {
			dm_output_to_console("%s", string_start);
			string_start = logger->log_buffer + logger->buffer_read_offset + 1;
		}
		logger->buffer_read_offset++;
	}
	if (should_warn)
		dm_output_to_console(
			"-------------- END FLUSHING LOG BUFFER --------------\n\n");
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Harry Wentland | 69 | 71.88% | 1 | 50.00% | 
| Dmytro Laktyushkin | 27 | 28.12% | 1 | 50.00% | 
| Total | 96 | 100.00% | 2 | 100.00% | 
static void log_to_internal_buffer(struct log_entry *entry)
{
	uint32_t size = entry->buf_offset;
	struct dal_logger *logger = entry->logger;
	if (logger->flags.bits.ENABLE_BUFFER == 0)
		return;
	if (logger->log_buffer == NULL)
		return;
	if (size > 0 && size < logger->log_buffer_size) {
		int buffer_space = logger->log_buffer_size -
				logger->buffer_write_offset;
		if (logger->buffer_write_offset == logger->buffer_read_offset) {
			/* Buffer is empty, start writing at beginning */
			buffer_space = logger->log_buffer_size;
			logger->buffer_write_offset = 0;
			logger->buffer_read_offset = 0;
		}
		if (buffer_space > size) {
			/* No wrap around, copy 'size' bytes
                         * from 'entry->buf' to 'log_buffer'
                         */
			memmove(logger->log_buffer +
					logger->buffer_write_offset,
					entry->buf, size);
			logger->buffer_write_offset += size;
		} else {
			/* Not enough room remaining, we should flush
                         * existing logs */
			/* Flush existing unread logs to console */
			dm_logger_flush_buffer(logger, true);
			/* Start writing to beginning of buffer */
			memmove(logger->log_buffer, entry->buf, size);
			logger->buffer_write_offset = size;
			logger->buffer_read_offset = 0;
		}
	}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Harry Wentland | 167 | 95.43% | 1 | 50.00% | 
| Dmytro Laktyushkin | 8 | 4.57% | 1 | 50.00% | 
| Total | 175 | 100.00% | 2 | 100.00% | 
static void log_heading(struct log_entry *entry)
{
	int j;
	for (j = 0; j < NUM_ELEMENTS(log_type_info_tbl); j++) {
		const struct dc_log_type_info *info = &log_type_info_tbl[j];
		if (info->type == entry->type)
			dm_logger_append(entry, "[%s]\t", info->name);
	}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Harry Wentland | 65 | 100.00% | 1 | 100.00% | 
| Total | 65 | 100.00% | 1 | 100.00% | 
static void append_entry(
		struct log_entry *entry,
		char *buffer,
		uint32_t buf_size)
{
	if (!entry->buf ||
		entry->buf_offset + buf_size > entry->max_buf_bytes
	) {
		BREAK_TO_DEBUGGER();
		return;
	}
	/* Todo: check if off by 1 byte due to \0 anywhere */
	memmove(entry->buf + entry->buf_offset, buffer, buf_size);
	entry->buf_offset += buf_size;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Harry Wentland | 63 | 100.00% | 1 | 100.00% | 
| Total | 63 | 100.00% | 1 | 100.00% | 
/* ------------------------------------------------------------------------ */
/* Warning: Be careful that 'msg' is null terminated and the total size is
 * less than DAL_LOGGER_BUFFER_MAX_LOG_LINE_SIZE (256) including '\0'
 */
void dm_logger_write(
	struct dal_logger *logger,
	enum dc_log_type log_type,
	const char *msg,
	...)
{
	if (logger && dal_logger_should_log(logger, log_type)) {
		uint32_t size;
		va_list args;
		char buffer[LOG_MAX_LINE_SIZE];
		struct log_entry entry;
		va_start(args, msg);
		entry.logger = logger;
		entry.buf = buffer;
		entry.buf_offset = 0;
		entry.max_buf_bytes = DAL_LOGGER_BUFFER_MAX_SIZE * sizeof(char);
		entry.type = log_type;
		log_heading(&entry);
		size = dm_log_to_buffer(
			buffer, LOG_MAX_LINE_SIZE - 1, msg, args);
		buffer[entry.buf_offset + size] = '\0';
		entry.buf_offset += size + 1;
		/* --Flush log_entry buffer-- */
		/* print to kernel console */
		log_to_debug_console(&entry);
		/* log internally for dsat */
		log_to_internal_buffer(&entry);
		va_end(args);
	}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Harry Wentland | 137 | 90.13% | 1 | 50.00% | 
| Dmytro Laktyushkin | 15 | 9.87% | 1 | 50.00% | 
| Total | 152 | 100.00% | 2 | 100.00% | 
/* Same as dm_logger_write, except without open() and close(), which must
 * be done separately.
 */
void dm_logger_append(
	struct log_entry *entry,
	const char *msg,
	...)
{
	struct dal_logger *logger;
	if (!entry) {
		BREAK_TO_DEBUGGER();
		return;
	}
	logger = entry->logger;
	if (logger && logger->open_count > 0 &&
		dal_logger_should_log(logger, entry->type)) {
		uint32_t size;
		va_list args;
		char buffer[LOG_MAX_LINE_SIZE];
		va_start(args, msg);
		size = dm_log_to_buffer(
			buffer, LOG_MAX_LINE_SIZE, msg, args);
		if (size < LOG_MAX_LINE_SIZE - 1) {
			append_entry(entry, buffer, size);
		} else {
			append_entry(entry, "LOG_ERROR, line too long\n", 27);
		}
		va_end(args);
	}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Harry Wentland | 128 | 100.00% | 1 | 100.00% | 
| Total | 128 | 100.00% | 1 | 100.00% | 
void dm_logger_open(
		struct dal_logger *logger,
		struct log_entry *entry, /* out */
		enum dc_log_type log_type)
{
	if (!entry) {
		BREAK_TO_DEBUGGER();
		return;
	}
	entry->type = log_type;
	entry->logger = logger;
	entry->buf = kzalloc(DAL_LOGGER_BUFFER_MAX_SIZE * sizeof(char),
			     GFP_KERNEL);
	entry->buf_offset = 0;
	entry->max_buf_bytes = DAL_LOGGER_BUFFER_MAX_SIZE * sizeof(char);
	logger->open_count++;
	log_heading(entry);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Harry Wentland | 86 | 100.00% | 2 | 100.00% | 
| Total | 86 | 100.00% | 2 | 100.00% | 
void dm_logger_close(struct log_entry *entry)
{
	struct dal_logger *logger = entry->logger;
	if (logger && logger->open_count > 0) {
		logger->open_count--;
	} else {
		BREAK_TO_DEBUGGER();
		goto cleanup;
	}
	/* --Flush log_entry buffer-- */
	/* print to kernel console */
	log_to_debug_console(entry);
	/* log internally for dsat */
	log_to_internal_buffer(entry);
	/* TODO: Write end heading */
cleanup:
	if (entry->buf) {
		kfree(entry->buf);
		entry->buf = NULL;
		entry->buf_offset = 0;
		entry->max_buf_bytes = 0;
	}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Harry Wentland | 94 | 100.00% | 2 | 100.00% | 
| Total | 94 | 100.00% | 2 | 100.00% | 
Overall Contributors
| Person | Tokens | Prop | Commits | CommitProp | 
| Harry Wentland | 1375 | 95.69% | 3 | 50.00% | 
| Dmytro Laktyushkin | 50 | 3.48% | 1 | 16.67% | 
| Jordan Lazare | 6 | 0.42% | 1 | 16.67% | 
| Corbin McElhanney | 6 | 0.42% | 1 | 16.67% | 
| Total | 1437 | 100.00% | 6 | 100.00% | 
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.