1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/* SMBUS message transfer tracepoints
3 *
4 * Copyright (C) 2013 Red Hat, Inc. All Rights Reserved.
5 * Written by David Howells (dhowells@redhat.com)
6 */
7#undef TRACE_SYSTEM
8#define TRACE_SYSTEM smbus
9
10#if !defined(_TRACE_SMBUS_H) || defined(TRACE_HEADER_MULTI_READ)
11#define _TRACE_SMBUS_H
12
13#include <linux/i2c.h>
14#include <linux/tracepoint.h>
15
16/*
17 * drivers/i2c/i2c-core-smbus.c
18 */
19
20/*
21 * i2c_smbus_xfer() write data or procedure call request
22 */
23TRACE_EVENT_CONDITION(smbus_write,
24	TP_PROTO(const struct i2c_adapter *adap,
25		 u16 addr, unsigned short flags,
26		 char read_write, u8 command, int protocol,
27		 const union i2c_smbus_data *data),
28	TP_ARGS(adap, addr, flags, read_write, command, protocol, data),
29	TP_CONDITION(read_write == I2C_SMBUS_WRITE ||
30		     protocol == I2C_SMBUS_PROC_CALL ||
31		     protocol == I2C_SMBUS_BLOCK_PROC_CALL),
32	TP_STRUCT__entry(
33		__field(int,	adapter_nr		)
34		__field(__u16,	addr			)
35		__field(__u16,	flags			)
36		__field(__u8,	command			)
37		__field(__u8,	len			)
38		__field(__u32,	protocol		)
39		__array(__u8, buf, I2C_SMBUS_BLOCK_MAX + 2)	),
40	TP_fast_assign(
41		__entry->adapter_nr = adap->nr;
42		__entry->addr = addr;
43		__entry->flags = flags;
44		__entry->command = command;
45		__entry->protocol = protocol;
46
47		switch (protocol) {
48		case I2C_SMBUS_BYTE_DATA:
49			__entry->len = 1;
50			goto copy;
51		case I2C_SMBUS_WORD_DATA:
52		case I2C_SMBUS_PROC_CALL:
53			__entry->len = 2;
54			goto copy;
55		case I2C_SMBUS_BLOCK_DATA:
56		case I2C_SMBUS_BLOCK_PROC_CALL:
57		case I2C_SMBUS_I2C_BLOCK_DATA:
58			__entry->len = data->block[0] + 1;
59		copy:
60			memcpy(__entry->buf, data->block, __entry->len);
61			break;
62		case I2C_SMBUS_QUICK:
63		case I2C_SMBUS_BYTE:
64		case I2C_SMBUS_I2C_BLOCK_BROKEN:
65		default:
66			__entry->len = 0;
67		}
68		       ),
69	TP_printk("i2c-%d a=%03x f=%04x c=%x %s l=%u [%*phD]",
70		  __entry->adapter_nr,
71		  __entry->addr,
72		  __entry->flags,
73		  __entry->command,
74		  __print_symbolic(__entry->protocol,
75				   { I2C_SMBUS_QUICK,		"QUICK"	},
76				   { I2C_SMBUS_BYTE,		"BYTE"	},
77				   { I2C_SMBUS_BYTE_DATA,		"BYTE_DATA" },
78				   { I2C_SMBUS_WORD_DATA,		"WORD_DATA" },
79				   { I2C_SMBUS_PROC_CALL,		"PROC_CALL" },
80				   { I2C_SMBUS_BLOCK_DATA,		"BLOCK_DATA" },
81				   { I2C_SMBUS_I2C_BLOCK_BROKEN,	"I2C_BLOCK_BROKEN" },
82				   { I2C_SMBUS_BLOCK_PROC_CALL,	"BLOCK_PROC_CALL" },
83				   { I2C_SMBUS_I2C_BLOCK_DATA,	"I2C_BLOCK_DATA" }),
84		  __entry->len,
85		  __entry->len, __entry->buf
86		  ));
87
88/*
89 * i2c_smbus_xfer() read data request
90 */
91TRACE_EVENT_CONDITION(smbus_read,
92	TP_PROTO(const struct i2c_adapter *adap,
93		 u16 addr, unsigned short flags,
94		 char read_write, u8 command, int protocol),
95	TP_ARGS(adap, addr, flags, read_write, command, protocol),
96	TP_CONDITION(!(read_write == I2C_SMBUS_WRITE ||
97		       protocol == I2C_SMBUS_PROC_CALL ||
98		       protocol == I2C_SMBUS_BLOCK_PROC_CALL)),
99	TP_STRUCT__entry(
100		__field(int,	adapter_nr		)
101		__field(__u16,	flags			)
102		__field(__u16,	addr			)
103		__field(__u8,	command			)
104		__field(__u32,	protocol		)
105		__array(__u8, buf, I2C_SMBUS_BLOCK_MAX + 2)	),
106	TP_fast_assign(
107		__entry->adapter_nr = adap->nr;
108		__entry->addr = addr;
109		__entry->flags = flags;
110		__entry->command = command;
111		__entry->protocol = protocol;
112		       ),
113	TP_printk("i2c-%d a=%03x f=%04x c=%x %s",
114		  __entry->adapter_nr,
115		  __entry->addr,
116		  __entry->flags,
117		  __entry->command,
118		  __print_symbolic(__entry->protocol,
119				   { I2C_SMBUS_QUICK,		"QUICK"	},
120				   { I2C_SMBUS_BYTE,		"BYTE"	},
121				   { I2C_SMBUS_BYTE_DATA,		"BYTE_DATA" },
122				   { I2C_SMBUS_WORD_DATA,		"WORD_DATA" },
123				   { I2C_SMBUS_PROC_CALL,		"PROC_CALL" },
124				   { I2C_SMBUS_BLOCK_DATA,		"BLOCK_DATA" },
125				   { I2C_SMBUS_I2C_BLOCK_BROKEN,	"I2C_BLOCK_BROKEN" },
126				   { I2C_SMBUS_BLOCK_PROC_CALL,	"BLOCK_PROC_CALL" },
127				   { I2C_SMBUS_I2C_BLOCK_DATA,	"I2C_BLOCK_DATA" })
128		  ));
129
130/*
131 * i2c_smbus_xfer() read data or procedure call reply
132 */
133TRACE_EVENT_CONDITION(smbus_reply,
134	TP_PROTO(const struct i2c_adapter *adap,
135		 u16 addr, unsigned short flags,
136		 char read_write, u8 command, int protocol,
137		 const union i2c_smbus_data *data, int res),
138	TP_ARGS(adap, addr, flags, read_write, command, protocol, data, res),
139	TP_CONDITION(res >= 0 && read_write == I2C_SMBUS_READ),
140	TP_STRUCT__entry(
141		__field(int,	adapter_nr		)
142		__field(__u16,	addr			)
143		__field(__u16,	flags			)
144		__field(__u8,	command			)
145		__field(__u8,	len			)
146		__field(__u32,	protocol		)
147		__array(__u8, buf, I2C_SMBUS_BLOCK_MAX + 2)	),
148	TP_fast_assign(
149		__entry->adapter_nr = adap->nr;
150		__entry->addr = addr;
151		__entry->flags = flags;
152		__entry->command = command;
153		__entry->protocol = protocol;
154
155		switch (protocol) {
156		case I2C_SMBUS_BYTE:
157		case I2C_SMBUS_BYTE_DATA:
158			__entry->len = 1;
159			goto copy;
160		case I2C_SMBUS_WORD_DATA:
161		case I2C_SMBUS_PROC_CALL:
162			__entry->len = 2;
163			goto copy;
164		case I2C_SMBUS_BLOCK_DATA:
165		case I2C_SMBUS_BLOCK_PROC_CALL:
166		case I2C_SMBUS_I2C_BLOCK_DATA:
167			__entry->len = data->block[0] + 1;
168		copy:
169			memcpy(__entry->buf, data->block, __entry->len);
170			break;
171		case I2C_SMBUS_QUICK:
172		case I2C_SMBUS_I2C_BLOCK_BROKEN:
173		default:
174			__entry->len = 0;
175		}
176		       ),
177	TP_printk("i2c-%d a=%03x f=%04x c=%x %s l=%u [%*phD]",
178		  __entry->adapter_nr,
179		  __entry->addr,
180		  __entry->flags,
181		  __entry->command,
182		  __print_symbolic(__entry->protocol,
183				   { I2C_SMBUS_QUICK,		"QUICK"	},
184				   { I2C_SMBUS_BYTE,		"BYTE"	},
185				   { I2C_SMBUS_BYTE_DATA,		"BYTE_DATA" },
186				   { I2C_SMBUS_WORD_DATA,		"WORD_DATA" },
187				   { I2C_SMBUS_PROC_CALL,		"PROC_CALL" },
188				   { I2C_SMBUS_BLOCK_DATA,		"BLOCK_DATA" },
189				   { I2C_SMBUS_I2C_BLOCK_BROKEN,	"I2C_BLOCK_BROKEN" },
190				   { I2C_SMBUS_BLOCK_PROC_CALL,	"BLOCK_PROC_CALL" },
191				   { I2C_SMBUS_I2C_BLOCK_DATA,	"I2C_BLOCK_DATA" }),
192		  __entry->len,
193		  __entry->len, __entry->buf
194		  ));
195
196/*
197 * i2c_smbus_xfer() result
198 */
199TRACE_EVENT(smbus_result,
200	    TP_PROTO(const struct i2c_adapter *adap,
201		     u16 addr, unsigned short flags,
202		     char read_write, u8 command, int protocol,
203		     int res),
204	    TP_ARGS(adap, addr, flags, read_write, command, protocol, res),
205	    TP_STRUCT__entry(
206		    __field(int,	adapter_nr		)
207		    __field(__u16,	addr			)
208		    __field(__u16,	flags			)
209		    __field(__u8,	read_write		)
210		    __field(__u8,	command			)
211		    __field(__s16,	res			)
212		    __field(__u32,	protocol		)
213			     ),
214	    TP_fast_assign(
215		    __entry->adapter_nr = adap->nr;
216		    __entry->addr = addr;
217		    __entry->flags = flags;
218		    __entry->read_write = read_write;
219		    __entry->command = command;
220		    __entry->protocol = protocol;
221		    __entry->res = res;
222			   ),
223	    TP_printk("i2c-%d a=%03x f=%04x c=%x %s %s res=%d",
224		      __entry->adapter_nr,
225		      __entry->addr,
226		      __entry->flags,
227		      __entry->command,
228		      __print_symbolic(__entry->protocol,
229				       { I2C_SMBUS_QUICK,		"QUICK"	},
230				       { I2C_SMBUS_BYTE,		"BYTE"	},
231				       { I2C_SMBUS_BYTE_DATA,		"BYTE_DATA" },
232				       { I2C_SMBUS_WORD_DATA,		"WORD_DATA" },
233				       { I2C_SMBUS_PROC_CALL,		"PROC_CALL" },
234				       { I2C_SMBUS_BLOCK_DATA,		"BLOCK_DATA" },
235				       { I2C_SMBUS_I2C_BLOCK_BROKEN,	"I2C_BLOCK_BROKEN" },
236				       { I2C_SMBUS_BLOCK_PROC_CALL,	"BLOCK_PROC_CALL" },
237				       { I2C_SMBUS_I2C_BLOCK_DATA,	"I2C_BLOCK_DATA" }),
238		      __entry->read_write == I2C_SMBUS_WRITE ? "wr" : "rd",
239		      __entry->res
240		      ));
241
242#endif /* _TRACE_SMBUS_H */
243
244/* This part must be outside protection */
245#include <trace/define_trace.h>
246