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 int 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