Here's a tentative patch on top of the previous one to split the messages.  I
haven't tested the I2C side yet and cannot test the SMBUS write.

Each is split four ways:

  (1) i2c/smbus_write - Show write request before submitting

  (2) i2c/smbus_read - Show read request before submitting

  (3) i2c/smbus_reply - Show read reply after submitting (if no failure)

  (4) i2c/smbus_result - Show operation result

So this might give you something like:
 
        ... i2c_write: i2c-5 #0 f=00 a=44 l=2 [0800]
        ... i2c_read: i2c-5 #1 f=01 a=44 l=1
        ... i2c_reply: i2c-5 #1 f=01 a=44 l=1 [fe]
        ... i2c_result: n=2 ret=2

from a single __i2c_transfer() given an array of two messages.

Or:

        ... smbus_read: i2c-0 a=51 f=00 c=fc BYTE_DATA
        ... smbus_reply: i2c-0 a=51 f=00 c=fc BYTE_DATA [41ff01000...]
        ... smbus_result: i2c-0 a=51 f=00 c=fc BYTE_DATA rd res=0

from a single i2c_smbus_xfer().

David
---
commit 31d5367657a64453d48b89b09296f7ebc6a5ee94
Author: David Howells <[email protected]>
Date:   Fri Dec 13 17:13:19 2013 +0000

    i2c: Split traces

diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index 2128e106ca97..0dbf0dcff6ce 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -1726,6 +1726,19 @@ int __i2c_transfer(struct i2c_adapter *adap, struct 
i2c_msg *msgs, int num)
        unsigned long orig_jiffies;
        int ret, try;
 
+       /* i2c_trace_msg gets enabled when tracepoint i2c_transfer gets
+        * enabled.  This is an efficient way of keeping the for-loop from
+        * being executed when not needed.
+        */
+       if (static_key_false(&i2c_trace_msg)) {
+               int i;
+               for (i = 0; i < num; i++)
+                       if (msgs[i].flags & I2C_M_RD)
+                               trace_i2c_read(adap, &msgs[i], i);
+                       else
+                               trace_i2c_write(adap, &msgs[i], i);
+       }
+
        /* Retry automatically on arbitration loss */
        orig_jiffies = jiffies;
        for (ret = 0, try = 0; try <= adap->retries; try++) {
@@ -1736,14 +1749,12 @@ int __i2c_transfer(struct i2c_adapter *adap, struct 
i2c_msg *msgs, int num)
                        break;
        }
 
-       /* i2c_trace_msg gets enabled when tracepoint i2c_transfer gets
-        * enabled.  This is an efficient way of keeping the for-loop from
-        * being executed when not needed.
-        */
        if (static_key_false(&i2c_trace_msg)) {
                int i;
-               for (i = 0; i < num; i++)
-                       trace_i2c_transfer(adap, &msgs[i], ret);
+               for (i = 0; i < ret; i++)
+                       if (msgs[i].flags & I2C_M_RD)
+                               trace_i2c_reply(adap, &msgs[i], i);
+               trace_i2c_result(adap, i, ret);
        }
 
        return ret;
@@ -2541,6 +2552,11 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 
addr, unsigned short flags,
        int try;
        s32 res;
 
+       if (read_write == I2C_SMBUS_WRITE)
+               trace_smbus_write(adapter, addr, flags, command, protocol, 
data);
+       else
+               trace_smbus_read(adapter, addr, flags, command, protocol);
+
        flags &= I2C_M_TEN | I2C_CLIENT_PEC | I2C_CLIENT_SCCB;
 
        if (adapter->algo->smbus_xfer) {
@@ -2572,8 +2588,11 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 
addr, unsigned short flags,
                                      command, protocol, data);
 
 trace:
-       trace_smbus_transfer(adapter, addr, flags, read_write,
-                            command, protocol, data, res);
+       if (read_write == I2C_SMBUS_READ)
+               trace_smbus_reply(adapter, addr, flags,
+                                 command, protocol, data);
+       trace_smbus_result(adapter, addr, flags, read_write,
+                          command, protocol, res);
 
        return res;
 }
diff --git a/include/trace/events/i2c.h b/include/trace/events/i2c.h
index ed366e145c8d..ca19f4948290 100644
--- a/include/trace/events/i2c.h
+++ b/include/trace/events/i2c.h
@@ -23,42 +23,259 @@
 extern void i2c_transfer_trace_reg(void);
 extern void i2c_transfer_trace_unreg(void);
 
-TRACE_EVENT_FN(i2c_transfer,
+/*
+ * __i2c_transfer() write request
+ */
+TRACE_EVENT_FN(i2c_write,
               TP_PROTO(const struct i2c_adapter *adap, const struct i2c_msg 
*msg,
-                       int ret),
-              TP_ARGS(adap, msg, ret),
+                       int num),
+              TP_ARGS(adap, msg, num),
               TP_STRUCT__entry(
-                      __field( int,    adapter_nr              )
+                      __field(int,     adapter_nr              )
+                      __field(__u16,   msg_nr                  )
                       __field(__u16,   addr                    )
                       __field(__u16,   flags                   )
                       __field(__u16,   len                     )
-                      __field(__s16,   ret                     )
                       __dynamic_array(__u8, buf, msg->len)     ),
               TP_fast_assign(
                       __entry->adapter_nr = adap->nr;
+                      __entry->msg_nr = num;
+                      __entry->addr = msg->addr;
+                      __entry->flags = msg->flags;
+                      __entry->len = msg->len;
+                      memcpy(__get_dynamic_array(buf), msg->buf, msg->len);
+                             ),
+              TP_printk("i2c-%d #%u f=%02x a=%02x l=%u [%*phN]",
+                        __entry->adapter_nr,
+                        __entry->msg_nr,
+                        __entry->flags,
+                        __entry->addr,
+                        __entry->len,
+                        __entry->len, __get_dynamic_array(buf)
+                        ),
+              i2c_transfer_trace_reg,
+              i2c_transfer_trace_unreg);
+
+/*
+ * __i2c_transfer() read request
+ */
+TRACE_EVENT_FN(i2c_read,
+              TP_PROTO(const struct i2c_adapter *adap, const struct i2c_msg 
*msg,
+                       int num),
+              TP_ARGS(adap, msg, num),
+              TP_STRUCT__entry(
+                      __field(int,     adapter_nr              )
+                      __field(__u16,   msg_nr                  )
+                      __field(__u16,   addr                    )
+                      __field(__u16,   flags                   )
+                      __field(__u16,   len                     )
+                               ),
+              TP_fast_assign(
+                      __entry->adapter_nr = adap->nr;
+                      __entry->msg_nr = num;
+                      __entry->addr = msg->addr;
+                      __entry->flags = msg->flags;
+                      __entry->len = msg->len;
+                             ),
+              TP_printk("i2c-%d #%u f=%02x a=%02x l=%u",
+                        __entry->adapter_nr,
+                        __entry->msg_nr,
+                        __entry->flags,
+                        __entry->addr,
+                        __entry->len
+                        ),
+              i2c_transfer_trace_reg,
+                      i2c_transfer_trace_unreg);
+
+/*
+ * __i2c_transfer() read reply
+ */
+TRACE_EVENT_FN(i2c_reply,
+              TP_PROTO(const struct i2c_adapter *adap, const struct i2c_msg 
*msg,
+                       int num),
+              TP_ARGS(adap, msg, num),
+              TP_STRUCT__entry(
+                      __field(int,     adapter_nr              )
+                      __field(__u16,   msg_nr                  )
+                      __field(__u16,   addr                    )
+                      __field(__u16,   flags                   )
+                      __field(__u16,   len                     )
+                      __dynamic_array(__u8, buf, msg->len)     ),
+              TP_fast_assign(
+                      __entry->adapter_nr = adap->nr;
+                      __entry->msg_nr = num;
                       __entry->addr = msg->addr;
                       __entry->flags = msg->flags;
                       __entry->len = msg->len;
-                      __entry->ret = ret;
                       memcpy(__get_dynamic_array(buf), msg->buf, msg->len);
                              ),
-              TP_printk("i2c-%d f=%02x a=%02x l=%u ret=%d [%*phN]",
+              TP_printk("i2c-%d #%u f=%02x a=%02x l=%u [%*phN]",
                         __entry->adapter_nr,
+                        __entry->msg_nr,
                         __entry->flags,
                         __entry->addr,
                         __entry->len,
-                        __entry->ret,
                         __entry->len, __get_dynamic_array(buf)
                         ),
               i2c_transfer_trace_reg,
               i2c_transfer_trace_unreg);
 
-TRACE_EVENT(smbus_transfer,
+/*
+ * __i2c_transfer() result
+ */
+TRACE_EVENT_FN(i2c_result,
+              TP_PROTO(const struct i2c_adapter *adap, int num, int ret),
+              TP_ARGS(adap, num, ret),
+              TP_STRUCT__entry(
+                      __field(int,     adapter_nr              )
+                      __field(__u16,   nr_msgs                 )
+                      __field(__s16,   ret                     )
+                               ),
+              TP_fast_assign(
+                      __entry->adapter_nr = adap->nr;
+                      __entry->nr_msgs = num;
+                      __entry->ret = ret;
+                             ),
+              TP_printk("i2c-%d n=%u ret=%d",
+                        __entry->adapter_nr,
+                        __entry->nr_msgs,
+                        __entry->ret
+                        ),
+              i2c_transfer_trace_reg,
+              i2c_transfer_trace_unreg);
+
+/*
+ * i2c_smbus_xfer() write request
+ */
+TRACE_EVENT(smbus_write,
+           TP_PROTO(const struct i2c_adapter *adap,
+                    u16 addr, unsigned short flags,
+                    u8 command, int protocol,
+                    const union i2c_smbus_data *data),
+           TP_ARGS(adap, addr, flags, command, protocol, data),
+           TP_STRUCT__entry(
+                   __field(int,        adapter_nr              )
+                   __field(__u16,      addr                    )
+                   __field(__u16,      flags                   )
+                   __field(__u8,       command                 )
+                   __field(__u32,      protocol                )
+                   __array(__u8, buf, I2C_SMBUS_BLOCK_MAX + 2) ),
+           TP_fast_assign(
+                   __entry->adapter_nr = adap->nr;
+                   __entry->addr = addr;
+                   __entry->flags = flags;
+                   __entry->command = command;
+                   __entry->protocol = protocol;
+                   memcpy(__entry->buf, data->block, I2C_SMBUS_BLOCK_MAX + 2);
+                          ),
+           TP_printk("i2c-%d a=%02x f=%02x c=%x %s [%*phN]",
+                     __entry->adapter_nr,
+                     __entry->addr,
+                     __entry->flags,
+                     __entry->command,
+                     __print_symbolic(__entry->protocol,
+                                      { I2C_SMBUS_QUICK,               "QUICK" 
},
+                                      { I2C_SMBUS_BYTE,                "BYTE"  
},
+                                      { I2C_SMBUS_BYTE_DATA,           
"BYTE_DATA" },
+                                      { I2C_SMBUS_WORD_DATA,           
"WORD_DATA" },
+                                      { I2C_SMBUS_PROC_CALL,           
"PROC_CALL" },
+                                      { I2C_SMBUS_BLOCK_DATA,          
"BLOCK_DATA" },
+                                      { I2C_SMBUS_I2C_BLOCK_BROKEN,    
"I2C_BLOCK_BROKEN" },
+                                      { I2C_SMBUS_BLOCK_PROC_CALL,     
"BLOCK_PROC_CALL" },
+                                      { I2C_SMBUS_I2C_BLOCK_DATA,      
"I2C_BLOCK_DATA" }),
+                     I2C_SMBUS_BLOCK_MAX + 2, __entry->buf
+                     ));
+
+/*
+ * i2c_smbus_xfer() read request
+ */
+TRACE_EVENT(smbus_read,
+           TP_PROTO(const struct i2c_adapter *adap,
+                    u16 addr, unsigned short flags,
+                    u8 command, int protocol),
+           TP_ARGS(adap, addr, flags, command, protocol),
+           TP_STRUCT__entry(
+                   __field(int,        adapter_nr              )
+                   __field(__u16,      addr                    )
+                   __field(__u16,      flags                   )
+                   __field(__u8,       command                 )
+                   __field(__u32,      protocol                )
+                   __array(__u8, buf, I2C_SMBUS_BLOCK_MAX + 2) ),
+           TP_fast_assign(
+                   __entry->adapter_nr = adap->nr;
+                   __entry->addr = addr;
+                   __entry->flags = flags;
+                   __entry->command = command;
+                   __entry->protocol = protocol;
+                          ),
+           TP_printk("i2c-%d a=%02x f=%02x c=%x %s",
+                     __entry->adapter_nr,
+                     __entry->addr,
+                     __entry->flags,
+                     __entry->command,
+                     __print_symbolic(__entry->protocol,
+                                      { I2C_SMBUS_QUICK,               "QUICK" 
},
+                                      { I2C_SMBUS_BYTE,                "BYTE"  
},
+                                      { I2C_SMBUS_BYTE_DATA,           
"BYTE_DATA" },
+                                      { I2C_SMBUS_WORD_DATA,           
"WORD_DATA" },
+                                      { I2C_SMBUS_PROC_CALL,           
"PROC_CALL" },
+                                      { I2C_SMBUS_BLOCK_DATA,          
"BLOCK_DATA" },
+                                      { I2C_SMBUS_I2C_BLOCK_BROKEN,    
"I2C_BLOCK_BROKEN" },
+                                      { I2C_SMBUS_BLOCK_PROC_CALL,     
"BLOCK_PROC_CALL" },
+                                      { I2C_SMBUS_I2C_BLOCK_DATA,      
"I2C_BLOCK_DATA" })
+                     ));
+
+/*
+ * i2c_smbus_xfer() read reply
+ */
+TRACE_EVENT(smbus_reply,
+           TP_PROTO(const struct i2c_adapter *adap,
+                    u16 addr, unsigned short flags,
+                    u8 command, int protocol,
+                    const union i2c_smbus_data *data),
+           TP_ARGS(adap, addr, flags, command, protocol, data),
+           TP_STRUCT__entry(
+                   __field(int,        adapter_nr              )
+                   __field(__u16,      addr                    )
+                   __field(__u16,      flags                   )
+                   __field(__u8,       command                 )
+                   __field(__u32,      protocol                )
+                   __array(__u8, buf, I2C_SMBUS_BLOCK_MAX + 2) ),
+           TP_fast_assign(
+                   __entry->adapter_nr = adap->nr;
+                   __entry->addr = addr;
+                   __entry->flags = flags;
+                   __entry->command = command;
+                   __entry->protocol = protocol;
+                   memcpy(__entry->buf, data->block, I2C_SMBUS_BLOCK_MAX + 2);
+                          ),
+           TP_printk("i2c-%d a=%02x f=%02x c=%x %s [%*phN]",
+                     __entry->adapter_nr,
+                     __entry->addr,
+                     __entry->flags,
+                     __entry->command,
+                     __print_symbolic(__entry->protocol,
+                                      { I2C_SMBUS_QUICK,               "QUICK" 
},
+                                      { I2C_SMBUS_BYTE,                "BYTE"  
},
+                                      { I2C_SMBUS_BYTE_DATA,           
"BYTE_DATA" },
+                                      { I2C_SMBUS_WORD_DATA,           
"WORD_DATA" },
+                                      { I2C_SMBUS_PROC_CALL,           
"PROC_CALL" },
+                                      { I2C_SMBUS_BLOCK_DATA,          
"BLOCK_DATA" },
+                                      { I2C_SMBUS_I2C_BLOCK_BROKEN,    
"I2C_BLOCK_BROKEN" },
+                                      { I2C_SMBUS_BLOCK_PROC_CALL,     
"BLOCK_PROC_CALL" },
+                                      { I2C_SMBUS_I2C_BLOCK_DATA,      
"I2C_BLOCK_DATA" }),
+                     I2C_SMBUS_BLOCK_MAX + 2, __entry->buf
+                     ));
+
+/*
+ * i2c_smbus_xfer() result
+ */
+TRACE_EVENT(smbus_result,
            TP_PROTO(const struct i2c_adapter *adap,
                     u16 addr, unsigned short flags,
                     char read_write, u8 command, int protocol,
-                    const union i2c_smbus_data *data, int res),
-           TP_ARGS(adap, addr, flags, read_write, command, protocol, data, 
res),
+                    int res),
+           TP_ARGS(adap, addr, flags, read_write, command, protocol, res),
            TP_STRUCT__entry(
                    __field(int,        adapter_nr              )
                    __field(__u16,      addr                    )
@@ -67,7 +284,7 @@ TRACE_EVENT(smbus_transfer,
                    __field(__u8,       command                 )
                    __field(__s16,      res                     )
                    __field(__u32,      protocol                )
-                   __array(__u8, buf, I2C_SMBUS_BLOCK_MAX + 2) ),
+                            ),
            TP_fast_assign(
                    __entry->adapter_nr = adap->nr;
                    __entry->addr = addr;
@@ -76,17 +293,24 @@ TRACE_EVENT(smbus_transfer,
                    __entry->command = command;
                    __entry->protocol = protocol;
                    __entry->res = res;
-                   memcpy(__entry->buf, data->block, I2C_SMBUS_BLOCK_MAX + 2);
                           ),
-           TP_printk("i2c-%d f=%02x a=%02x r=%x c=%x p=%x res=%d [%*phN]",
+           TP_printk("i2c-%d a=%02x f=%02x c=%x %s %s res=%d",
                      __entry->adapter_nr,
-                     __entry->flags,
                      __entry->addr,
-                     __entry->read_write,
+                     __entry->flags,
                      __entry->command,
-                     __entry->protocol,
-                     __entry->res,
-                     I2C_SMBUS_BLOCK_MAX + 2, __entry->buf
+                     __print_symbolic(__entry->protocol,
+                                      { I2C_SMBUS_QUICK,               "QUICK" 
},
+                                      { I2C_SMBUS_BYTE,                "BYTE"  
},
+                                      { I2C_SMBUS_BYTE_DATA,           
"BYTE_DATA" },
+                                      { I2C_SMBUS_WORD_DATA,           
"WORD_DATA" },
+                                      { I2C_SMBUS_PROC_CALL,           
"PROC_CALL" },
+                                      { I2C_SMBUS_BLOCK_DATA,          
"BLOCK_DATA" },
+                                      { I2C_SMBUS_I2C_BLOCK_BROKEN,    
"I2C_BLOCK_BROKEN" },
+                                      { I2C_SMBUS_BLOCK_PROC_CALL,     
"BLOCK_PROC_CALL" },
+                                      { I2C_SMBUS_I2C_BLOCK_DATA,      
"I2C_BLOCK_DATA" }),
+                     __entry->read_write == I2C_SMBUS_WRITE ? "wr" : "rd",
+                     __entry->res
                      ));
 
 #endif /* _TRACE_I2C_H */
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to