You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
290 lines
8.5 KiB
290 lines
8.5 KiB
/* Copyright (c) 2012-2015,2017 The Linux Foundation. All rights reserved.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 and
|
|
* only version 2 as published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*/
|
|
|
|
#ifndef _IPC_LOGGING_H
|
|
#define _IPC_LOGGING_H
|
|
|
|
#include <linux/types.h>
|
|
|
|
#define MAX_MSG_SIZE 255
|
|
|
|
enum {
|
|
TSV_TYPE_MSG_START = 1,
|
|
TSV_TYPE_SKB = TSV_TYPE_MSG_START,
|
|
TSV_TYPE_STRING,
|
|
TSV_TYPE_MSG_END = TSV_TYPE_STRING,
|
|
};
|
|
|
|
struct tsv_header {
|
|
unsigned char type;
|
|
unsigned char size; /* size of data field */
|
|
};
|
|
|
|
struct encode_context {
|
|
struct tsv_header hdr;
|
|
char buff[MAX_MSG_SIZE];
|
|
int offset;
|
|
};
|
|
|
|
struct decode_context {
|
|
int output_format; /* 0 = debugfs */
|
|
char *buff; /* output buffer */
|
|
int size; /* size of output buffer */
|
|
};
|
|
|
|
#if defined(CONFIG_IPC_LOGGING)
|
|
/*
|
|
* ipc_log_context_create: Create a debug log context
|
|
* Should not be called from atomic context
|
|
*
|
|
* @max_num_pages: Number of pages of logging space required (max. 10)
|
|
* @mod_name : Name of the directory entry under DEBUGFS
|
|
* @user_version : Version number of user-defined message formats
|
|
*
|
|
* returns context id on success, NULL on failure
|
|
*/
|
|
void *ipc_log_context_create(int max_num_pages, const char *modname,
|
|
uint16_t user_version);
|
|
|
|
/*
|
|
* msg_encode_start: Start encoding a log message
|
|
*
|
|
* @ectxt: Temporary storage to hold the encoded message
|
|
* @type: Root event type defined by the module which is logging
|
|
*/
|
|
void msg_encode_start(struct encode_context *ectxt, uint32_t type);
|
|
|
|
/*
|
|
* tsv_timestamp_write: Writes the current timestamp count
|
|
*
|
|
* @ectxt: Context initialized by calling msg_encode_start()
|
|
*/
|
|
int tsv_timestamp_write(struct encode_context *ectxt);
|
|
|
|
/*
|
|
* tsv_qtimer_write: Writes the current QTimer timestamp count
|
|
*
|
|
* @ectxt: Context initialized by calling msg_encode_start()
|
|
*/
|
|
int tsv_qtimer_write(struct encode_context *ectxt);
|
|
|
|
/*
|
|
* tsv_pointer_write: Writes a data pointer
|
|
*
|
|
* @ectxt: Context initialized by calling msg_encode_start()
|
|
* @pointer: Pointer value to write
|
|
*/
|
|
int tsv_pointer_write(struct encode_context *ectxt, void *pointer);
|
|
|
|
/*
|
|
* tsv_int32_write: Writes a 32-bit integer value
|
|
*
|
|
* @ectxt: Context initialized by calling msg_encode_start()
|
|
* @n: Integer to write
|
|
*/
|
|
int tsv_int32_write(struct encode_context *ectxt, int32_t n);
|
|
|
|
/*
|
|
* tsv_int32_write: Writes a 32-bit integer value
|
|
*
|
|
* @ectxt: Context initialized by calling msg_encode_start()
|
|
* @n: Integer to write
|
|
*/
|
|
int tsv_byte_array_write(struct encode_context *ectxt,
|
|
void *data, int data_size);
|
|
|
|
/*
|
|
* msg_encode_end: Complete the message encode process
|
|
*
|
|
* @ectxt: Temporary storage which holds the encoded message
|
|
*/
|
|
void msg_encode_end(struct encode_context *ectxt);
|
|
|
|
/*
|
|
* msg_encode_end: Complete the message encode process
|
|
*
|
|
* @ectxt: Temporary storage which holds the encoded message
|
|
*/
|
|
void ipc_log_write(void *ctxt, struct encode_context *ectxt);
|
|
|
|
/*
|
|
* ipc_log_string: Helper function to log a string
|
|
*
|
|
* @ilctxt: Debug Log Context created using ipc_log_context_create()
|
|
* @fmt: Data specified using format specifiers
|
|
*/
|
|
int ipc_log_string(void *ilctxt, const char *fmt, ...) __printf(2, 3);
|
|
|
|
/**
|
|
* ipc_log_extract - Reads and deserializes log
|
|
*
|
|
* @ilctxt: logging context
|
|
* @buff: buffer to receive the data
|
|
* @size: size of the buffer
|
|
* @returns: 0 if no data read; >0 number of bytes read; < 0 error
|
|
*
|
|
* If no data is available to be read, then the ilctxt::read_avail
|
|
* completion is reinitialized. This allows clients to block
|
|
* until new log data is save.
|
|
*/
|
|
int ipc_log_extract(void *ilctxt, char *buff, int size);
|
|
|
|
/*
|
|
* Print a string to decode context.
|
|
* @dctxt Decode context
|
|
* @args printf args
|
|
*/
|
|
#define IPC_SPRINTF_DECODE(dctxt, args...) \
|
|
do { \
|
|
int i; \
|
|
i = scnprintf(dctxt->buff, dctxt->size, args); \
|
|
dctxt->buff += i; \
|
|
dctxt->size -= i; \
|
|
} while (0)
|
|
|
|
/*
|
|
* tsv_timestamp_read: Reads a timestamp
|
|
*
|
|
* @ectxt: Context retrieved by reading from log space
|
|
* @dctxt: Temporary storage to hold the decoded message
|
|
* @format: Output format while dumping through DEBUGFS
|
|
*/
|
|
void tsv_timestamp_read(struct encode_context *ectxt,
|
|
struct decode_context *dctxt, const char *format);
|
|
|
|
/*
|
|
* tsv_qtimer_read: Reads a QTimer timestamp
|
|
*
|
|
* @ectxt: Context retrieved by reading from log space
|
|
* @dctxt: Temporary storage to hold the decoded message
|
|
* @format: Output format while dumping through DEBUGFS
|
|
*/
|
|
void tsv_qtimer_read(struct encode_context *ectxt,
|
|
struct decode_context *dctxt, const char *format);
|
|
|
|
/*
|
|
* tsv_pointer_read: Reads a data pointer
|
|
*
|
|
* @ectxt: Context retrieved by reading from log space
|
|
* @dctxt: Temporary storage to hold the decoded message
|
|
* @format: Output format while dumping through DEBUGFS
|
|
*/
|
|
void tsv_pointer_read(struct encode_context *ectxt,
|
|
struct decode_context *dctxt, const char *format);
|
|
|
|
/*
|
|
* tsv_int32_read: Reads a 32-bit integer value
|
|
*
|
|
* @ectxt: Context retrieved by reading from log space
|
|
* @dctxt: Temporary storage to hold the decoded message
|
|
* @format: Output format while dumping through DEBUGFS
|
|
*/
|
|
int32_t tsv_int32_read(struct encode_context *ectxt,
|
|
struct decode_context *dctxt, const char *format);
|
|
|
|
/*
|
|
* tsv_int32_read: Reads a 32-bit integer value
|
|
*
|
|
* @ectxt: Context retrieved by reading from log space
|
|
* @dctxt: Temporary storage to hold the decoded message
|
|
* @format: Output format while dumping through DEBUGFS
|
|
*/
|
|
void tsv_byte_array_read(struct encode_context *ectxt,
|
|
struct decode_context *dctxt, const char *format);
|
|
|
|
/*
|
|
* add_deserialization_func: Register a deserialization function to
|
|
* to unpack the subevents of a main event
|
|
*
|
|
* @ctxt: Debug log context to which the deserialization function has
|
|
* to be registered
|
|
* @type: Main/Root event, defined by the module which is logging, to
|
|
* which this deserialization function has to be registered.
|
|
* @dfune: Deserialization function to be registered
|
|
*
|
|
* return 0 on success, -ve value on FAILURE
|
|
*/
|
|
int add_deserialization_func(void *ctxt, int type,
|
|
void (*dfunc)(struct encode_context *,
|
|
struct decode_context *));
|
|
|
|
/*
|
|
* ipc_log_context_destroy: Destroy debug log context
|
|
*
|
|
* @ctxt: debug log context created by calling ipc_log_context_create API.
|
|
*/
|
|
int ipc_log_context_destroy(void *ctxt);
|
|
|
|
#else
|
|
|
|
static inline void *ipc_log_context_create(int max_num_pages,
|
|
const char *modname, uint16_t user_version)
|
|
{ return NULL; }
|
|
|
|
static inline void msg_encode_start(struct encode_context *ectxt,
|
|
uint32_t type) { }
|
|
|
|
static inline int tsv_timestamp_write(struct encode_context *ectxt)
|
|
{ return -EINVAL; }
|
|
|
|
static inline int tsv_qtimer_write(struct encode_context *ectxt)
|
|
{ return -EINVAL; }
|
|
|
|
static inline int tsv_pointer_write(struct encode_context *ectxt, void *pointer)
|
|
{ return -EINVAL; }
|
|
|
|
static inline int tsv_int32_write(struct encode_context *ectxt, int32_t n)
|
|
{ return -EINVAL; }
|
|
|
|
static inline int tsv_byte_array_write(struct encode_context *ectxt,
|
|
void *data, int data_size)
|
|
{ return -EINVAL; }
|
|
|
|
static inline void msg_encode_end(struct encode_context *ectxt) { }
|
|
|
|
static inline void ipc_log_write(void *ctxt, struct encode_context *ectxt) { }
|
|
|
|
static inline int ipc_log_string(void *ilctxt, const char *fmt, ...)
|
|
{ return -EINVAL; }
|
|
|
|
static inline int ipc_log_extract(void *ilctxt, char *buff, int size)
|
|
{ return -EINVAL; }
|
|
|
|
#define IPC_SPRINTF_DECODE(dctxt, args...) do { } while (0)
|
|
|
|
static inline void tsv_timestamp_read(struct encode_context *ectxt,
|
|
struct decode_context *dctxt, const char *format) { }
|
|
|
|
static inline void tsv_qtimer_read(struct encode_context *ectxt,
|
|
struct decode_context *dctxt, const char *format) { }
|
|
|
|
static inline void tsv_pointer_read(struct encode_context *ectxt,
|
|
struct decode_context *dctxt, const char *format) { }
|
|
|
|
static inline int32_t tsv_int32_read(struct encode_context *ectxt,
|
|
struct decode_context *dctxt, const char *format)
|
|
{ return 0; }
|
|
|
|
static inline void tsv_byte_array_read(struct encode_context *ectxt,
|
|
struct decode_context *dctxt, const char *format) { }
|
|
|
|
static inline int add_deserialization_func(void *ctxt, int type,
|
|
void (*dfunc)(struct encode_context *,
|
|
struct decode_context *))
|
|
{ return 0; }
|
|
|
|
static inline int ipc_log_context_destroy(void *ctxt)
|
|
{ return 0; }
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|