i2c.h 11 KB

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