scsi: ufs: Add trace event for UIC commands
authorStanley Chu <stanley.chu@mediatek.com>
Mon, 15 Jun 2020 07:22:35 +0000 (15:22 +0800)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 16 Jun 2020 03:35:06 +0000 (23:35 -0400)
Use the ftrace infrastructure to conditionally trace UFS UIC command
events.

New trace event "ufshcd_uic_command" is created, which samples the
following UFS UIC command data:

 - Device name
 - Optional identification string
 - UIC command opcode
 - UIC command argument1
 - UIC command argument2
 - UIC command argement3

Usage:
echo 1 > /sys/kernel/debug/tracing/events/ufs/enable
cat /sys/kernel/debug/tracing/trace_pipe

Link: https://lore.kernel.org/r/20200615072235.23042-3-stanley.chu@mediatek.com
Acked-by: Avri Altman <avri.altman@wdc.com>
Signed-off-by: Stanley Chu <stanley.chu@mediatek.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/ufs/ufshcd.c
include/trace/events/ufs.h

index 6cedf07..19221de 100644 (file)
@@ -311,6 +311,26 @@ static void ufshcd_add_tm_upiu_trace(struct ufs_hba *hba, unsigned int tag,
                        &descp->input_param1);
 }
 
+static void ufshcd_add_uic_command_trace(struct ufs_hba *hba,
+                                        struct uic_command *ucmd,
+                                        const char *str)
+{
+       u32 cmd;
+
+       if (!trace_ufshcd_uic_command_enabled())
+               return;
+
+       if (!strcmp(str, "send"))
+               cmd = ucmd->command;
+       else
+               cmd = ufshcd_readl(hba, REG_UIC_COMMAND);
+
+       trace_ufshcd_uic_command(dev_name(hba->dev), str, cmd,
+                                ufshcd_readl(hba, REG_UIC_COMMAND_ARG_1),
+                                ufshcd_readl(hba, REG_UIC_COMMAND_ARG_2),
+                                ufshcd_readl(hba, REG_UIC_COMMAND_ARG_3));
+}
+
 static void ufshcd_add_command_trace(struct ufs_hba *hba,
                unsigned int tag, const char *str)
 {
@@ -2030,6 +2050,8 @@ ufshcd_dispatch_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd)
        ufshcd_writel(hba, uic_cmd->argument2, REG_UIC_COMMAND_ARG_2);
        ufshcd_writel(hba, uic_cmd->argument3, REG_UIC_COMMAND_ARG_3);
 
+       ufshcd_add_uic_command_trace(hba, uic_cmd, "send");
+
        /* Write UIC Cmd */
        ufshcd_writel(hba, uic_cmd->command & COMMAND_OPCODE_MASK,
                      REG_UIC_COMMAND);
@@ -4835,6 +4857,10 @@ static irqreturn_t ufshcd_uic_cmd_compl(struct ufs_hba *hba, u32 intr_status)
                complete(hba->uic_async_done);
                retval = IRQ_HANDLED;
        }
+
+       if (retval == IRQ_HANDLED)
+               ufshcd_add_uic_command_trace(hba, hba->active_uic_cmd,
+                                            "complete");
        return retval;
 }
 
index 5f30073..84841b3 100644 (file)
@@ -249,6 +249,37 @@ TRACE_EVENT(ufshcd_command,
        )
 );
 
+TRACE_EVENT(ufshcd_uic_command,
+       TP_PROTO(const char *dev_name, const char *str, u32 cmd,
+                u32 arg1, u32 arg2, u32 arg3),
+
+       TP_ARGS(dev_name, str, cmd, arg1, arg2, arg3),
+
+       TP_STRUCT__entry(
+               __string(dev_name, dev_name)
+               __string(str, str)
+               __field(u32, cmd)
+               __field(u32, arg1)
+               __field(u32, arg2)
+               __field(u32, arg3)
+       ),
+
+       TP_fast_assign(
+               __assign_str(dev_name, dev_name);
+               __assign_str(str, str);
+               __entry->cmd = cmd;
+               __entry->arg1 = arg1;
+               __entry->arg2 = arg2;
+               __entry->arg3 = arg3;
+       ),
+
+       TP_printk(
+               "%s: %s: cmd: 0x%x, arg1: 0x%x, arg2: 0x%x, arg3: 0x%x",
+               __get_str(str), __get_str(dev_name), __entry->cmd,
+               __entry->arg1, __entry->arg2, __entry->arg3
+       )
+);
+
 TRACE_EVENT(ufshcd_upiu,
        TP_PROTO(const char *dev_name, const char *str, void *hdr, void *tsf),