mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-05 18:39:59 +00:00
![Ohad Sharabi](/assets/img/avatar_default.png)
Add UFS Protocol Information Units(upiu) trace events for ufs driver, used to trace various ufs transaction types- command, task-management and device management. The trace-point format is generic and can be easily adapted to trace other upius if needed. Currently tracing ufs transaction of type 'device management', which this patch introduce, cannot be obtained from any other trace. Device management transactions are used for communication with the device such as reading and writing descriptor or attributes etc. Signed-off-by: Ohad Sharabi <ohad.sharabi@sandisk.com> Reviewed-by: Stanislav Nijnikov <stanislav.nijnikov@wdc.com> Reviewed-by: Bart Van Assche <bart.vanassche@wdc.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
290 lines
7.5 KiB
C
290 lines
7.5 KiB
C
/*
|
|
* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 and
|
|
* only version 2 as published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*/
|
|
|
|
#undef TRACE_SYSTEM
|
|
#define TRACE_SYSTEM ufs
|
|
|
|
#if !defined(_TRACE_UFS_H) || defined(TRACE_HEADER_MULTI_READ)
|
|
#define _TRACE_UFS_H
|
|
|
|
#include <linux/tracepoint.h>
|
|
|
|
#define UFS_LINK_STATES \
|
|
EM(UIC_LINK_OFF_STATE) \
|
|
EM(UIC_LINK_ACTIVE_STATE) \
|
|
EMe(UIC_LINK_HIBERN8_STATE)
|
|
|
|
#define UFS_PWR_MODES \
|
|
EM(UFS_ACTIVE_PWR_MODE) \
|
|
EM(UFS_SLEEP_PWR_MODE) \
|
|
EMe(UFS_POWERDOWN_PWR_MODE)
|
|
|
|
#define UFSCHD_CLK_GATING_STATES \
|
|
EM(CLKS_OFF) \
|
|
EM(CLKS_ON) \
|
|
EM(REQ_CLKS_OFF) \
|
|
EMe(REQ_CLKS_ON)
|
|
|
|
/* Enums require being exported to userspace, for user tool parsing */
|
|
#undef EM
|
|
#undef EMe
|
|
#define EM(a) TRACE_DEFINE_ENUM(a);
|
|
#define EMe(a) TRACE_DEFINE_ENUM(a);
|
|
|
|
UFS_LINK_STATES;
|
|
UFS_PWR_MODES;
|
|
UFSCHD_CLK_GATING_STATES;
|
|
|
|
/*
|
|
* Now redefine the EM() and EMe() macros to map the enums to the strings
|
|
* that will be printed in the output.
|
|
*/
|
|
#undef EM
|
|
#undef EMe
|
|
#define EM(a) { a, #a },
|
|
#define EMe(a) { a, #a }
|
|
|
|
TRACE_EVENT(ufshcd_clk_gating,
|
|
|
|
TP_PROTO(const char *dev_name, int state),
|
|
|
|
TP_ARGS(dev_name, state),
|
|
|
|
TP_STRUCT__entry(
|
|
__string(dev_name, dev_name)
|
|
__field(int, state)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__assign_str(dev_name, dev_name);
|
|
__entry->state = state;
|
|
),
|
|
|
|
TP_printk("%s: gating state changed to %s",
|
|
__get_str(dev_name),
|
|
__print_symbolic(__entry->state, UFSCHD_CLK_GATING_STATES))
|
|
);
|
|
|
|
TRACE_EVENT(ufshcd_clk_scaling,
|
|
|
|
TP_PROTO(const char *dev_name, const char *state, const char *clk,
|
|
u32 prev_state, u32 curr_state),
|
|
|
|
TP_ARGS(dev_name, state, clk, prev_state, curr_state),
|
|
|
|
TP_STRUCT__entry(
|
|
__string(dev_name, dev_name)
|
|
__string(state, state)
|
|
__string(clk, clk)
|
|
__field(u32, prev_state)
|
|
__field(u32, curr_state)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__assign_str(dev_name, dev_name);
|
|
__assign_str(state, state);
|
|
__assign_str(clk, clk);
|
|
__entry->prev_state = prev_state;
|
|
__entry->curr_state = curr_state;
|
|
),
|
|
|
|
TP_printk("%s: %s %s from %u to %u Hz",
|
|
__get_str(dev_name), __get_str(state), __get_str(clk),
|
|
__entry->prev_state, __entry->curr_state)
|
|
);
|
|
|
|
TRACE_EVENT(ufshcd_auto_bkops_state,
|
|
|
|
TP_PROTO(const char *dev_name, const char *state),
|
|
|
|
TP_ARGS(dev_name, state),
|
|
|
|
TP_STRUCT__entry(
|
|
__string(dev_name, dev_name)
|
|
__string(state, state)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__assign_str(dev_name, dev_name);
|
|
__assign_str(state, state);
|
|
),
|
|
|
|
TP_printk("%s: auto bkops - %s",
|
|
__get_str(dev_name), __get_str(state))
|
|
);
|
|
|
|
DECLARE_EVENT_CLASS(ufshcd_profiling_template,
|
|
TP_PROTO(const char *dev_name, const char *profile_info, s64 time_us,
|
|
int err),
|
|
|
|
TP_ARGS(dev_name, profile_info, time_us, err),
|
|
|
|
TP_STRUCT__entry(
|
|
__string(dev_name, dev_name)
|
|
__string(profile_info, profile_info)
|
|
__field(s64, time_us)
|
|
__field(int, err)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__assign_str(dev_name, dev_name);
|
|
__assign_str(profile_info, profile_info);
|
|
__entry->time_us = time_us;
|
|
__entry->err = err;
|
|
),
|
|
|
|
TP_printk("%s: %s: took %lld usecs, err %d",
|
|
__get_str(dev_name), __get_str(profile_info),
|
|
__entry->time_us, __entry->err)
|
|
);
|
|
|
|
DEFINE_EVENT(ufshcd_profiling_template, ufshcd_profile_hibern8,
|
|
TP_PROTO(const char *dev_name, const char *profile_info, s64 time_us,
|
|
int err),
|
|
TP_ARGS(dev_name, profile_info, time_us, err));
|
|
|
|
DEFINE_EVENT(ufshcd_profiling_template, ufshcd_profile_clk_gating,
|
|
TP_PROTO(const char *dev_name, const char *profile_info, s64 time_us,
|
|
int err),
|
|
TP_ARGS(dev_name, profile_info, time_us, err));
|
|
|
|
DEFINE_EVENT(ufshcd_profiling_template, ufshcd_profile_clk_scaling,
|
|
TP_PROTO(const char *dev_name, const char *profile_info, s64 time_us,
|
|
int err),
|
|
TP_ARGS(dev_name, profile_info, time_us, err));
|
|
|
|
DECLARE_EVENT_CLASS(ufshcd_template,
|
|
TP_PROTO(const char *dev_name, int err, s64 usecs,
|
|
int dev_state, int link_state),
|
|
|
|
TP_ARGS(dev_name, err, usecs, dev_state, link_state),
|
|
|
|
TP_STRUCT__entry(
|
|
__field(s64, usecs)
|
|
__field(int, err)
|
|
__string(dev_name, dev_name)
|
|
__field(int, dev_state)
|
|
__field(int, link_state)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__entry->usecs = usecs;
|
|
__entry->err = err;
|
|
__assign_str(dev_name, dev_name);
|
|
__entry->dev_state = dev_state;
|
|
__entry->link_state = link_state;
|
|
),
|
|
|
|
TP_printk(
|
|
"%s: took %lld usecs, dev_state: %s, link_state: %s, err %d",
|
|
__get_str(dev_name),
|
|
__entry->usecs,
|
|
__print_symbolic(__entry->dev_state, UFS_PWR_MODES),
|
|
__print_symbolic(__entry->link_state, UFS_LINK_STATES),
|
|
__entry->err
|
|
)
|
|
);
|
|
|
|
DEFINE_EVENT(ufshcd_template, ufshcd_system_suspend,
|
|
TP_PROTO(const char *dev_name, int err, s64 usecs,
|
|
int dev_state, int link_state),
|
|
TP_ARGS(dev_name, err, usecs, dev_state, link_state));
|
|
|
|
DEFINE_EVENT(ufshcd_template, ufshcd_system_resume,
|
|
TP_PROTO(const char *dev_name, int err, s64 usecs,
|
|
int dev_state, int link_state),
|
|
TP_ARGS(dev_name, err, usecs, dev_state, link_state));
|
|
|
|
DEFINE_EVENT(ufshcd_template, ufshcd_runtime_suspend,
|
|
TP_PROTO(const char *dev_name, int err, s64 usecs,
|
|
int dev_state, int link_state),
|
|
TP_ARGS(dev_name, err, usecs, dev_state, link_state));
|
|
|
|
DEFINE_EVENT(ufshcd_template, ufshcd_runtime_resume,
|
|
TP_PROTO(const char *dev_name, int err, s64 usecs,
|
|
int dev_state, int link_state),
|
|
TP_ARGS(dev_name, err, usecs, dev_state, link_state));
|
|
|
|
DEFINE_EVENT(ufshcd_template, ufshcd_init,
|
|
TP_PROTO(const char *dev_name, int err, s64 usecs,
|
|
int dev_state, int link_state),
|
|
TP_ARGS(dev_name, err, usecs, dev_state, link_state));
|
|
|
|
TRACE_EVENT(ufshcd_command,
|
|
TP_PROTO(const char *dev_name, const char *str, unsigned int tag,
|
|
u32 doorbell, int transfer_len, u32 intr, u64 lba,
|
|
u8 opcode),
|
|
|
|
TP_ARGS(dev_name, str, tag, doorbell, transfer_len, intr, lba, opcode),
|
|
|
|
TP_STRUCT__entry(
|
|
__string(dev_name, dev_name)
|
|
__string(str, str)
|
|
__field(unsigned int, tag)
|
|
__field(u32, doorbell)
|
|
__field(int, transfer_len)
|
|
__field(u32, intr)
|
|
__field(u64, lba)
|
|
__field(u8, opcode)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__assign_str(dev_name, dev_name);
|
|
__assign_str(str, str);
|
|
__entry->tag = tag;
|
|
__entry->doorbell = doorbell;
|
|
__entry->transfer_len = transfer_len;
|
|
__entry->intr = intr;
|
|
__entry->lba = lba;
|
|
__entry->opcode = opcode;
|
|
),
|
|
|
|
TP_printk(
|
|
"%s: %s: tag: %u, DB: 0x%x, size: %d, IS: %u, LBA: %llu, opcode: 0x%x",
|
|
__get_str(str), __get_str(dev_name), __entry->tag,
|
|
__entry->doorbell, __entry->transfer_len,
|
|
__entry->intr, __entry->lba, (u32)__entry->opcode
|
|
)
|
|
);
|
|
|
|
TRACE_EVENT(ufshcd_upiu,
|
|
TP_PROTO(const char *dev_name, const char *str, void *hdr, void *tsf),
|
|
|
|
TP_ARGS(dev_name, str, hdr, tsf),
|
|
|
|
TP_STRUCT__entry(
|
|
__string(dev_name, dev_name)
|
|
__string(str, str)
|
|
__array(unsigned char, hdr, 12)
|
|
__array(unsigned char, tsf, 16)
|
|
),
|
|
|
|
TP_fast_assign(
|
|
__assign_str(dev_name, dev_name);
|
|
__assign_str(str, str);
|
|
memcpy(__entry->hdr, hdr, sizeof(__entry->hdr));
|
|
memcpy(__entry->tsf, tsf, sizeof(__entry->tsf));
|
|
),
|
|
|
|
TP_printk(
|
|
"%s: %s: HDR:%s, CDB:%s",
|
|
__get_str(str), __get_str(dev_name),
|
|
__print_hex(__entry->hdr, sizeof(__entry->hdr)),
|
|
__print_hex(__entry->tsf, sizeof(__entry->tsf))
|
|
)
|
|
);
|
|
|
|
#endif /* if !defined(_TRACE_UFS_H) || defined(TRACE_HEADER_MULTI_READ) */
|
|
|
|
/* This part must be outside protection */
|
|
#include <trace/define_trace.h>
|