• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* I2C and SMBUS message transfer tracepoints
2  *
3  * Copyright (C) 2013 Red Hat, Inc. All Rights Reserved.
4  * Written by David Howells (dhowells@redhat.com)
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public Licence
8  * as published by the Free Software Foundation; either version
9  * 2 of the Licence, or (at your option) any later version.
10  */
11 #undef TRACE_SYSTEM
12 #define TRACE_SYSTEM i2c
13 
14 #if !defined(_TRACE_I2C_H) || defined(TRACE_HEADER_MULTI_READ)
15 #define _TRACE_I2C_H
16 
17 #include <linux/i2c.h>
18 #include <linux/tracepoint.h>
19 
20 /*
21  * drivers/i2c/i2c-core.c
22  */
23 extern void i2c_transfer_trace_reg(void);
24 extern void i2c_transfer_trace_unreg(void);
25 
26 /*
27  * __i2c_transfer() write request
28  */
29 TRACE_EVENT_FN(i2c_write,
30 	       TP_PROTO(const struct i2c_adapter *adap, const struct i2c_msg *msg,
31 			int num),
32 	       TP_ARGS(adap, msg, num),
33 	       TP_STRUCT__entry(
34 		       __field(int,	adapter_nr		)
35 		       __field(__u16,	msg_nr			)
36 		       __field(__u16,	addr			)
37 		       __field(__u16,	flags			)
38 		       __field(__u16,	len			)
39 		       __dynamic_array(__u8, buf, msg->len)	),
40 	       TP_fast_assign(
41 		       __entry->adapter_nr = adap->nr;
42 		       __entry->msg_nr = num;
43 		       __entry->addr = msg->addr;
44 		       __entry->flags = msg->flags;
45 		       __entry->len = msg->len;
46 		       memcpy(__get_dynamic_array(buf), msg->buf, msg->len);
47 			      ),
48 	       TP_printk("i2c-%d #%u a=%03x f=%04x l=%u [%*phD]",
49 			 __entry->adapter_nr,
50 			 __entry->msg_nr,
51 			 __entry->addr,
52 			 __entry->flags,
53 			 __entry->len,
54 			 __entry->len, __get_dynamic_array(buf)
55 			 ),
56 	       i2c_transfer_trace_reg,
57 	       i2c_transfer_trace_unreg);
58 
59 /*
60  * __i2c_transfer() read request
61  */
62 TRACE_EVENT_FN(i2c_read,
63 	       TP_PROTO(const struct i2c_adapter *adap, const struct i2c_msg *msg,
64 			int num),
65 	       TP_ARGS(adap, msg, num),
66 	       TP_STRUCT__entry(
67 		       __field(int,	adapter_nr		)
68 		       __field(__u16,	msg_nr			)
69 		       __field(__u16,	addr			)
70 		       __field(__u16,	flags			)
71 		       __field(__u16,	len			)
72 				),
73 	       TP_fast_assign(
74 		       __entry->adapter_nr = adap->nr;
75 		       __entry->msg_nr = num;
76 		       __entry->addr = msg->addr;
77 		       __entry->flags = msg->flags;
78 		       __entry->len = msg->len;
79 			      ),
80 	       TP_printk("i2c-%d #%u a=%03x f=%04x l=%u",
81 			 __entry->adapter_nr,
82 			 __entry->msg_nr,
83 			 __entry->addr,
84 			 __entry->flags,
85 			 __entry->len
86 			 ),
87 	       i2c_transfer_trace_reg,
88 		       i2c_transfer_trace_unreg);
89 
90 /*
91  * __i2c_transfer() read reply
92  */
93 TRACE_EVENT_FN(i2c_reply,
94 	       TP_PROTO(const struct i2c_adapter *adap, const struct i2c_msg *msg,
95 			int num),
96 	       TP_ARGS(adap, msg, num),
97 	       TP_STRUCT__entry(
98 		       __field(int,	adapter_nr		)
99 		       __field(__u16,	msg_nr			)
100 		       __field(__u16,	addr			)
101 		       __field(__u16,	flags			)
102 		       __field(__u16,	len			)
103 		       __dynamic_array(__u8, buf, msg->len)	),
104 	       TP_fast_assign(
105 		       __entry->adapter_nr = adap->nr;
106 		       __entry->msg_nr = num;
107 		       __entry->addr = msg->addr;
108 		       __entry->flags = msg->flags;
109 		       __entry->len = msg->len;
110 		       memcpy(__get_dynamic_array(buf), msg->buf, msg->len);
111 			      ),
112 	       TP_printk("i2c-%d #%u a=%03x f=%04x l=%u [%*phD]",
113 			 __entry->adapter_nr,
114 			 __entry->msg_nr,
115 			 __entry->addr,
116 			 __entry->flags,
117 			 __entry->len,
118 			 __entry->len, __get_dynamic_array(buf)
119 			 ),
120 	       i2c_transfer_trace_reg,
121 	       i2c_transfer_trace_unreg);
122 
123 /*
124  * __i2c_transfer() result
125  */
126 TRACE_EVENT_FN(i2c_result,
127 	       TP_PROTO(const struct i2c_adapter *adap, int num, int ret),
128 	       TP_ARGS(adap, num, ret),
129 	       TP_STRUCT__entry(
130 		       __field(int,	adapter_nr		)
131 		       __field(__u16,	nr_msgs			)
132 		       __field(__s16,	ret			)
133 				),
134 	       TP_fast_assign(
135 		       __entry->adapter_nr = adap->nr;
136 		       __entry->nr_msgs = num;
137 		       __entry->ret = ret;
138 			      ),
139 	       TP_printk("i2c-%d n=%u ret=%d",
140 			 __entry->adapter_nr,
141 			 __entry->nr_msgs,
142 			 __entry->ret
143 			 ),
144 	       i2c_transfer_trace_reg,
145 	       i2c_transfer_trace_unreg);
146 
147 /*
148  * i2c_smbus_xfer() write data or procedure call request
149  */
150 TRACE_EVENT_CONDITION(smbus_write,
151 	TP_PROTO(const struct i2c_adapter *adap,
152 		 u16 addr, unsigned short flags,
153 		 char read_write, u8 command, int protocol,
154 		 const union i2c_smbus_data *data),
155 	TP_ARGS(adap, addr, flags, read_write, command, protocol, data),
156 	TP_CONDITION(read_write == I2C_SMBUS_WRITE ||
157 		     protocol == I2C_SMBUS_PROC_CALL ||
158 		     protocol == I2C_SMBUS_BLOCK_PROC_CALL),
159 	TP_STRUCT__entry(
160 		__field(int,	adapter_nr		)
161 		__field(__u16,	addr			)
162 		__field(__u16,	flags			)
163 		__field(__u8,	command			)
164 		__field(__u8,	len			)
165 		__field(__u32,	protocol		)
166 		__array(__u8, buf, I2C_SMBUS_BLOCK_MAX + 2)	),
167 	TP_fast_assign(
168 		__entry->adapter_nr = adap->nr;
169 		__entry->addr = addr;
170 		__entry->flags = flags;
171 		__entry->command = command;
172 		__entry->protocol = protocol;
173 
174 		switch (protocol) {
175 		case I2C_SMBUS_BYTE_DATA:
176 			__entry->len = 1;
177 			goto copy;
178 		case I2C_SMBUS_WORD_DATA:
179 		case I2C_SMBUS_PROC_CALL:
180 			__entry->len = 2;
181 			goto copy;
182 		case I2C_SMBUS_BLOCK_DATA:
183 		case I2C_SMBUS_BLOCK_PROC_CALL:
184 		case I2C_SMBUS_I2C_BLOCK_DATA:
185 			__entry->len = data->block[0] + 1;
186 		copy:
187 			memcpy(__entry->buf, data->block, __entry->len);
188 			break;
189 		case I2C_SMBUS_QUICK:
190 		case I2C_SMBUS_BYTE:
191 		case I2C_SMBUS_I2C_BLOCK_BROKEN:
192 		default:
193 			__entry->len = 0;
194 		}
195 		       ),
196 	TP_printk("i2c-%d a=%03x f=%04x c=%x %s l=%u [%*phD]",
197 		  __entry->adapter_nr,
198 		  __entry->addr,
199 		  __entry->flags,
200 		  __entry->command,
201 		  __print_symbolic(__entry->protocol,
202 				   { I2C_SMBUS_QUICK,		"QUICK"	},
203 				   { I2C_SMBUS_BYTE,		"BYTE"	},
204 				   { I2C_SMBUS_BYTE_DATA,		"BYTE_DATA" },
205 				   { I2C_SMBUS_WORD_DATA,		"WORD_DATA" },
206 				   { I2C_SMBUS_PROC_CALL,		"PROC_CALL" },
207 				   { I2C_SMBUS_BLOCK_DATA,		"BLOCK_DATA" },
208 				   { I2C_SMBUS_I2C_BLOCK_BROKEN,	"I2C_BLOCK_BROKEN" },
209 				   { I2C_SMBUS_BLOCK_PROC_CALL,	"BLOCK_PROC_CALL" },
210 				   { I2C_SMBUS_I2C_BLOCK_DATA,	"I2C_BLOCK_DATA" }),
211 		  __entry->len,
212 		  __entry->len, __entry->buf
213 		  ));
214 
215 /*
216  * i2c_smbus_xfer() read data request
217  */
218 TRACE_EVENT_CONDITION(smbus_read,
219 	TP_PROTO(const struct i2c_adapter *adap,
220 		 u16 addr, unsigned short flags,
221 		 char read_write, u8 command, int protocol),
222 	TP_ARGS(adap, addr, flags, read_write, command, protocol),
223 	TP_CONDITION(!(read_write == I2C_SMBUS_WRITE ||
224 		       protocol == I2C_SMBUS_PROC_CALL ||
225 		       protocol == I2C_SMBUS_BLOCK_PROC_CALL)),
226 	TP_STRUCT__entry(
227 		__field(int,	adapter_nr		)
228 		__field(__u16,	flags			)
229 		__field(__u16,	addr			)
230 		__field(__u8,	command			)
231 		__field(__u32,	protocol		)
232 		__array(__u8, buf, I2C_SMBUS_BLOCK_MAX + 2)	),
233 	TP_fast_assign(
234 		__entry->adapter_nr = adap->nr;
235 		__entry->addr = addr;
236 		__entry->flags = flags;
237 		__entry->command = command;
238 		__entry->protocol = protocol;
239 		       ),
240 	TP_printk("i2c-%d a=%03x f=%04x c=%x %s",
241 		  __entry->adapter_nr,
242 		  __entry->addr,
243 		  __entry->flags,
244 		  __entry->command,
245 		  __print_symbolic(__entry->protocol,
246 				   { I2C_SMBUS_QUICK,		"QUICK"	},
247 				   { I2C_SMBUS_BYTE,		"BYTE"	},
248 				   { I2C_SMBUS_BYTE_DATA,		"BYTE_DATA" },
249 				   { I2C_SMBUS_WORD_DATA,		"WORD_DATA" },
250 				   { I2C_SMBUS_PROC_CALL,		"PROC_CALL" },
251 				   { I2C_SMBUS_BLOCK_DATA,		"BLOCK_DATA" },
252 				   { I2C_SMBUS_I2C_BLOCK_BROKEN,	"I2C_BLOCK_BROKEN" },
253 				   { I2C_SMBUS_BLOCK_PROC_CALL,	"BLOCK_PROC_CALL" },
254 				   { I2C_SMBUS_I2C_BLOCK_DATA,	"I2C_BLOCK_DATA" })
255 		  ));
256 
257 /*
258  * i2c_smbus_xfer() read data or procedure call reply
259  */
260 TRACE_EVENT_CONDITION(smbus_reply,
261 	TP_PROTO(const struct i2c_adapter *adap,
262 		 u16 addr, unsigned short flags,
263 		 char read_write, u8 command, int protocol,
264 		 const union i2c_smbus_data *data),
265 	TP_ARGS(adap, addr, flags, read_write, command, protocol, data),
266 	TP_CONDITION(read_write == I2C_SMBUS_READ),
267 	TP_STRUCT__entry(
268 		__field(int,	adapter_nr		)
269 		__field(__u16,	addr			)
270 		__field(__u16,	flags			)
271 		__field(__u8,	command			)
272 		__field(__u8,	len			)
273 		__field(__u32,	protocol		)
274 		__array(__u8, buf, I2C_SMBUS_BLOCK_MAX + 2)	),
275 	TP_fast_assign(
276 		__entry->adapter_nr = adap->nr;
277 		__entry->addr = addr;
278 		__entry->flags = flags;
279 		__entry->command = command;
280 		__entry->protocol = protocol;
281 
282 		switch (protocol) {
283 		case I2C_SMBUS_BYTE:
284 		case I2C_SMBUS_BYTE_DATA:
285 			__entry->len = 1;
286 			goto copy;
287 		case I2C_SMBUS_WORD_DATA:
288 		case I2C_SMBUS_PROC_CALL:
289 			__entry->len = 2;
290 			goto copy;
291 		case I2C_SMBUS_BLOCK_DATA:
292 		case I2C_SMBUS_BLOCK_PROC_CALL:
293 		case I2C_SMBUS_I2C_BLOCK_DATA:
294 			__entry->len = data->block[0] + 1;
295 		copy:
296 			memcpy(__entry->buf, data->block, __entry->len);
297 			break;
298 		case I2C_SMBUS_QUICK:
299 		case I2C_SMBUS_I2C_BLOCK_BROKEN:
300 		default:
301 			__entry->len = 0;
302 		}
303 		       ),
304 	TP_printk("i2c-%d a=%03x f=%04x c=%x %s l=%u [%*phD]",
305 		  __entry->adapter_nr,
306 		  __entry->addr,
307 		  __entry->flags,
308 		  __entry->command,
309 		  __print_symbolic(__entry->protocol,
310 				   { I2C_SMBUS_QUICK,		"QUICK"	},
311 				   { I2C_SMBUS_BYTE,		"BYTE"	},
312 				   { I2C_SMBUS_BYTE_DATA,		"BYTE_DATA" },
313 				   { I2C_SMBUS_WORD_DATA,		"WORD_DATA" },
314 				   { I2C_SMBUS_PROC_CALL,		"PROC_CALL" },
315 				   { I2C_SMBUS_BLOCK_DATA,		"BLOCK_DATA" },
316 				   { I2C_SMBUS_I2C_BLOCK_BROKEN,	"I2C_BLOCK_BROKEN" },
317 				   { I2C_SMBUS_BLOCK_PROC_CALL,	"BLOCK_PROC_CALL" },
318 				   { I2C_SMBUS_I2C_BLOCK_DATA,	"I2C_BLOCK_DATA" }),
319 		  __entry->len,
320 		  __entry->len, __entry->buf
321 		  ));
322 
323 /*
324  * i2c_smbus_xfer() result
325  */
326 TRACE_EVENT(smbus_result,
327 	    TP_PROTO(const struct i2c_adapter *adap,
328 		     u16 addr, unsigned short flags,
329 		     char read_write, u8 command, int protocol,
330 		     int res),
331 	    TP_ARGS(adap, addr, flags, read_write, command, protocol, res),
332 	    TP_STRUCT__entry(
333 		    __field(int,	adapter_nr		)
334 		    __field(__u16,	addr			)
335 		    __field(__u16,	flags			)
336 		    __field(__u8,	read_write		)
337 		    __field(__u8,	command			)
338 		    __field(__s16,	res			)
339 		    __field(__u32,	protocol		)
340 			     ),
341 	    TP_fast_assign(
342 		    __entry->adapter_nr = adap->nr;
343 		    __entry->addr = addr;
344 		    __entry->flags = flags;
345 		    __entry->read_write = read_write;
346 		    __entry->command = command;
347 		    __entry->protocol = protocol;
348 		    __entry->res = res;
349 			   ),
350 	    TP_printk("i2c-%d a=%03x f=%04x c=%x %s %s res=%d",
351 		      __entry->adapter_nr,
352 		      __entry->addr,
353 		      __entry->flags,
354 		      __entry->command,
355 		      __print_symbolic(__entry->protocol,
356 				       { I2C_SMBUS_QUICK,		"QUICK"	},
357 				       { I2C_SMBUS_BYTE,		"BYTE"	},
358 				       { I2C_SMBUS_BYTE_DATA,		"BYTE_DATA" },
359 				       { I2C_SMBUS_WORD_DATA,		"WORD_DATA" },
360 				       { I2C_SMBUS_PROC_CALL,		"PROC_CALL" },
361 				       { I2C_SMBUS_BLOCK_DATA,		"BLOCK_DATA" },
362 				       { I2C_SMBUS_I2C_BLOCK_BROKEN,	"I2C_BLOCK_BROKEN" },
363 				       { I2C_SMBUS_BLOCK_PROC_CALL,	"BLOCK_PROC_CALL" },
364 				       { I2C_SMBUS_I2C_BLOCK_DATA,	"I2C_BLOCK_DATA" }),
365 		      __entry->read_write == I2C_SMBUS_WRITE ? "wr" : "rd",
366 		      __entry->res
367 		      ));
368 
369 #endif /* _TRACE_I2C_H */
370 
371 /* This part must be outside protection */
372 #include <trace/define_trace.h>
373