blob: 98a25072c4c2e35be0bdd5e00a8cda0b2135f752 [file] [log] [blame]
Dhoat Harpalf76b2362018-03-22 20:37:38 +05301/* Copyright (c) 2012-2015, 2018 The Linux Foundation. All rights reserved.
Chris Lew3c8356762016-08-01 15:18:55 -07002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#ifndef _IPC_LOGGING_H
14#define _IPC_LOGGING_H
15
16#include <linux/types.h>
jiangjiae8cebd62019-03-07 17:11:02 +080017#include <linux/err.h>
Chris Lew3c8356762016-08-01 15:18:55 -070018
19#define MAX_MSG_SIZE 255
20
21enum {
22 TSV_TYPE_MSG_START = 1,
23 TSV_TYPE_SKB = TSV_TYPE_MSG_START,
24 TSV_TYPE_STRING,
25 TSV_TYPE_MSG_END = TSV_TYPE_STRING,
26};
27
28struct tsv_header {
29 unsigned char type;
30 unsigned char size; /* size of data field */
31};
32
33struct encode_context {
34 struct tsv_header hdr;
35 char buff[MAX_MSG_SIZE];
36 int offset;
37};
38
39struct decode_context {
40 int output_format; /* 0 = debugfs */
41 char *buff; /* output buffer */
42 int size; /* size of output buffer */
43};
44
45#if defined(CONFIG_IPC_LOGGING)
46/*
47 * ipc_log_context_create: Create a debug log context
48 * Should not be called from atomic context
49 *
50 * @max_num_pages: Number of pages of logging space required (max. 10)
51 * @mod_name : Name of the directory entry under DEBUGFS
52 * @user_version : Version number of user-defined message formats
53 *
54 * returns context id on success, NULL on failure
55 */
56void *ipc_log_context_create(int max_num_pages, const char *modname,
57 uint16_t user_version);
58
59/*
60 * msg_encode_start: Start encoding a log message
61 *
62 * @ectxt: Temporary storage to hold the encoded message
63 * @type: Root event type defined by the module which is logging
64 */
65void msg_encode_start(struct encode_context *ectxt, uint32_t type);
66
67/*
68 * tsv_timestamp_write: Writes the current timestamp count
69 *
70 * @ectxt: Context initialized by calling msg_encode_start()
71 */
72int tsv_timestamp_write(struct encode_context *ectxt);
73
74/*
75 * tsv_qtimer_write: Writes the current QTimer timestamp count
76 *
77 * @ectxt: Context initialized by calling msg_encode_start()
78 */
79int tsv_qtimer_write(struct encode_context *ectxt);
80
81/*
82 * tsv_pointer_write: Writes a data pointer
83 *
84 * @ectxt: Context initialized by calling msg_encode_start()
85 * @pointer: Pointer value to write
86 */
87int tsv_pointer_write(struct encode_context *ectxt, void *pointer);
88
89/*
90 * tsv_int32_write: Writes a 32-bit integer value
91 *
92 * @ectxt: Context initialized by calling msg_encode_start()
93 * @n: Integer to write
94 */
95int tsv_int32_write(struct encode_context *ectxt, int32_t n);
96
97/*
98 * tsv_int32_write: Writes a 32-bit integer value
99 *
100 * @ectxt: Context initialized by calling msg_encode_start()
101 * @n: Integer to write
102 */
103int tsv_byte_array_write(struct encode_context *ectxt,
104 void *data, int data_size);
105
106/*
107 * msg_encode_end: Complete the message encode process
108 *
109 * @ectxt: Temporary storage which holds the encoded message
110 */
111void msg_encode_end(struct encode_context *ectxt);
112
113/*
114 * msg_encode_end: Complete the message encode process
115 *
116 * @ectxt: Temporary storage which holds the encoded message
117 */
118void ipc_log_write(void *ctxt, struct encode_context *ectxt);
119
120/*
121 * ipc_log_string: Helper function to log a string
122 *
123 * @ilctxt: Debug Log Context created using ipc_log_context_create()
124 * @fmt: Data specified using format specifiers
125 */
126int ipc_log_string(void *ilctxt, const char *fmt, ...) __printf(2, 3);
127
Dhoat Harpalf76b2362018-03-22 20:37:38 +0530128/*
129 * ipc_log_ctrl_all - disable/enable logging in all clients
130 *
131 * @ Data specified using format specifiers
132 */
133void ipc_log_ctrl_all(bool disable);
134
Chris Lew3c8356762016-08-01 15:18:55 -0700135/**
136 * ipc_log_extract - Reads and deserializes log
137 *
138 * @ilctxt: logging context
139 * @buff: buffer to receive the data
140 * @size: size of the buffer
141 * @returns: 0 if no data read; >0 number of bytes read; < 0 error
142 *
143 * If no data is available to be read, then the ilctxt::read_avail
144 * completion is reinitialized. This allows clients to block
145 * until new log data is save.
146 */
147int ipc_log_extract(void *ilctxt, char *buff, int size);
148
149/*
150 * Print a string to decode context.
151 * @dctxt Decode context
152 * @args printf args
153 */
154#define IPC_SPRINTF_DECODE(dctxt, args...) \
155do { \
156 int i; \
157 i = scnprintf(dctxt->buff, dctxt->size, args); \
158 dctxt->buff += i; \
159 dctxt->size -= i; \
160} while (0)
161
162/*
163 * tsv_timestamp_read: Reads a timestamp
164 *
165 * @ectxt: Context retrieved by reading from log space
166 * @dctxt: Temporary storage to hold the decoded message
167 * @format: Output format while dumping through DEBUGFS
168 */
169void tsv_timestamp_read(struct encode_context *ectxt,
170 struct decode_context *dctxt, const char *format);
171
172/*
173 * tsv_qtimer_read: Reads a QTimer timestamp
174 *
175 * @ectxt: Context retrieved by reading from log space
176 * @dctxt: Temporary storage to hold the decoded message
177 * @format: Output format while dumping through DEBUGFS
178 */
179void tsv_qtimer_read(struct encode_context *ectxt,
180 struct decode_context *dctxt, const char *format);
181
182/*
183 * tsv_pointer_read: Reads a data pointer
184 *
185 * @ectxt: Context retrieved by reading from log space
186 * @dctxt: Temporary storage to hold the decoded message
187 * @format: Output format while dumping through DEBUGFS
188 */
189void tsv_pointer_read(struct encode_context *ectxt,
190 struct decode_context *dctxt, const char *format);
191
192/*
193 * tsv_int32_read: Reads a 32-bit integer value
194 *
195 * @ectxt: Context retrieved by reading from log space
196 * @dctxt: Temporary storage to hold the decoded message
197 * @format: Output format while dumping through DEBUGFS
198 */
199int32_t tsv_int32_read(struct encode_context *ectxt,
200 struct decode_context *dctxt, const char *format);
201
202/*
203 * tsv_int32_read: Reads a 32-bit integer value
204 *
205 * @ectxt: Context retrieved by reading from log space
206 * @dctxt: Temporary storage to hold the decoded message
207 * @format: Output format while dumping through DEBUGFS
208 */
209void tsv_byte_array_read(struct encode_context *ectxt,
210 struct decode_context *dctxt, const char *format);
211
212/*
213 * add_deserialization_func: Register a deserialization function to
214 * to unpack the subevents of a main event
215 *
216 * @ctxt: Debug log context to which the deserialization function has
217 * to be registered
218 * @type: Main/Root event, defined by the module which is logging, to
219 * which this deserialization function has to be registered.
220 * @dfune: Deserialization function to be registered
221 *
222 * return 0 on success, -ve value on FAILURE
223 */
224int add_deserialization_func(void *ctxt, int type,
225 void (*dfunc)(struct encode_context *,
226 struct decode_context *));
227
228/*
229 * ipc_log_context_destroy: Destroy debug log context
230 *
231 * @ctxt: debug log context created by calling ipc_log_context_create API.
232 */
233int ipc_log_context_destroy(void *ctxt);
234
235#else
236
237static inline void *ipc_log_context_create(int max_num_pages,
238 const char *modname, uint16_t user_version)
239{ return NULL; }
240
241static inline void msg_encode_start(struct encode_context *ectxt,
242 uint32_t type) { }
243
244static inline int tsv_timestamp_write(struct encode_context *ectxt)
245{ return -EINVAL; }
246
247static inline int tsv_qtimer_write(struct encode_context *ectxt)
248{ return -EINVAL; }
249
250static inline int tsv_pointer_write(struct encode_context *ectxt, void *pointer)
251{ return -EINVAL; }
252
253static inline int tsv_int32_write(struct encode_context *ectxt, int32_t n)
254{ return -EINVAL; }
255
256static inline int tsv_byte_array_write(struct encode_context *ectxt,
257 void *data, int data_size)
258{ return -EINVAL; }
259
260static inline void msg_encode_end(struct encode_context *ectxt) { }
261
262static inline void ipc_log_write(void *ctxt, struct encode_context *ectxt) { }
263
264static inline int ipc_log_string(void *ilctxt, const char *fmt, ...)
265{ return -EINVAL; }
266
267static inline int ipc_log_extract(void *ilctxt, char *buff, int size)
268{ return -EINVAL; }
269
270#define IPC_SPRINTF_DECODE(dctxt, args...) do { } while (0)
271
272static inline void tsv_timestamp_read(struct encode_context *ectxt,
273 struct decode_context *dctxt, const char *format) { }
274
275static inline void tsv_qtimer_read(struct encode_context *ectxt,
276 struct decode_context *dctxt, const char *format) { }
277
278static inline void tsv_pointer_read(struct encode_context *ectxt,
279 struct decode_context *dctxt, const char *format) { }
280
281static inline int32_t tsv_int32_read(struct encode_context *ectxt,
282 struct decode_context *dctxt, const char *format)
283{ return 0; }
284
285static inline void tsv_byte_array_read(struct encode_context *ectxt,
286 struct decode_context *dctxt, const char *format) { }
287
288static inline int add_deserialization_func(void *ctxt, int type,
289 void (*dfunc)(struct encode_context *,
290 struct decode_context *))
291{ return 0; }
292
293static inline int ipc_log_context_destroy(void *ctxt)
294{ return 0; }
295
296#endif
297
298#endif