Re: [PATCH v5 3/3] scsi: ufs: add trace events and dump prints for debug

2015-03-12 Thread Gilad Broner
> This and the auto_bkops_state is pretty much the same. Can't you use
> the same TP_printk() and just have a DECLARE_EVENT_CLASS? The trace
> point name is printed with the event to see different events.

I agree. will upload the fix in next patchset.

-- 
Qualcomm Israel, on behalf of Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v5 3/3] scsi: ufs: add trace events and dump prints for debug

2015-03-12 Thread Gilad Broner
 This and the auto_bkops_state is pretty much the same. Can't you use
 the same TP_printk() and just have a DECLARE_EVENT_CLASS? The trace
 point name is printed with the event to see different events.

I agree. will upload the fix in next patchset.

-- 
Qualcomm Israel, on behalf of Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH v5 3/3] scsi: ufs: add trace events and dump prints for debug

2015-03-10 Thread Steven Rostedt
On Tue, 10 Mar 2015 13:47:15 +0200
Gilad Broner  wrote:


> +++ b/include/trace/events/ufs.h
> @@ -0,0 +1,227 @@
> +/*
> + * Copyright (c) 2013-2015, 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 
> +
> +TRACE_EVENT(ufshcd_clk_gating,
> +
> + 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: gating state changed to %s",
> + __get_str(dev_name), __get_str(state))
> +);

This and the auto_bkops_state is pretty much the same. Can't you use
the same TP_printk() and just have a DECLARE_EVENT_CLASS? The trace
point name is printed with the event to see different events.

At least use DEFINE_EVENT_PRINT() that lets you override a EVENT_CLASS
TP_printk(). This saves memory.

-- Steve


> +
> +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))
> +);
> +
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v5 3/3] scsi: ufs: add trace events and dump prints for debug

2015-03-10 Thread Gilad Broner
Add trace events to driver to allow monitoring and profilig
of activities such as PM suspend/resume, hibernate enter/exit,
clock gating and clock scaling up/down.
In addition, add UFS host controller register dumps to provide
detailed information in case of errors to assist in analysis
of issues.

Signed-off-by: Dolev Raviv 
Signed-off-by: Subhash Jadavani 
Signed-off-by: Lee Susman 
Signed-off-by: Sujit Reddy Thumma 
Signed-off-by: Yaniv Gardi 
---
 drivers/scsi/ufs/ufs-qcom.c |  53 +
 drivers/scsi/ufs/ufshcd.c   | 511 +---
 drivers/scsi/ufs/ufshcd.h   |  49 -
 drivers/scsi/ufs/ufshci.h   |   1 +
 include/trace/events/ufs.h  | 227 
 5 files changed, 804 insertions(+), 37 deletions(-)
 create mode 100644 include/trace/events/ufs.h

diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c
index 9217af9..9fe675d 100644
--- a/drivers/scsi/ufs/ufs-qcom.c
+++ b/drivers/scsi/ufs/ufs-qcom.c
@@ -30,6 +30,14 @@ static int ufs_qcom_get_bus_vote(struct ufs_qcom_host *host,
const char *speed_mode);
 static int ufs_qcom_set_bus_vote(struct ufs_qcom_host *host, int vote);
 
+static void ufs_qcom_dump_regs(struct ufs_hba *hba, int offset, int len,
+   char *prefix)
+{
+   print_hex_dump(KERN_ERR, prefix,
+   len > 4 ? DUMP_PREFIX_OFFSET : DUMP_PREFIX_NONE,
+   16, 4, hba->mmio_base + offset, len * 4, false);
+}
+
 static int ufs_qcom_get_connected_tx_lanes(struct ufs_hba *hba, u32 *tx_lanes)
 {
int err = 0;
@@ -983,6 +991,50 @@ void ufs_qcom_clk_scale_notify(struct ufs_hba *hba)
dev_req_params->hs_rate);
 }
 
+static void ufs_qcom_print_hw_debug_reg_all(struct ufs_hba *hba)
+{
+   u32 reg;
+
+   ufs_qcom_dump_regs(hba, UFS_UFS_DBG_RD_REG_OCSC, 44,
+   "UFS_UFS_DBG_RD_REG_OCSC ");
+
+   reg = ufshcd_readl(hba, REG_UFS_CFG1);
+   reg |= UFS_BIT(17);
+   ufshcd_writel(hba, reg, REG_UFS_CFG1);
+
+   ufs_qcom_dump_regs(hba, UFS_UFS_DBG_RD_EDTL_RAM, 32,
+   "UFS_UFS_DBG_RD_EDTL_RAM ");
+   ufs_qcom_dump_regs(hba, UFS_UFS_DBG_RD_DESC_RAM, 128,
+   "UFS_UFS_DBG_RD_DESC_RAM ");
+   ufs_qcom_dump_regs(hba, UFS_UFS_DBG_RD_PRDT_RAM, 64,
+   "UFS_UFS_DBG_RD_PRDT_RAM ");
+
+   ufshcd_writel(hba, (reg & ~UFS_BIT(17)), REG_UFS_CFG1);
+
+   ufs_qcom_dump_regs(hba, UFS_DBG_RD_REG_UAWM, 4,
+   "UFS_DBG_RD_REG_UAWM ");
+   ufs_qcom_dump_regs(hba, UFS_DBG_RD_REG_UARM, 4,
+   "UFS_DBG_RD_REG_UARM ");
+   ufs_qcom_dump_regs(hba, UFS_DBG_RD_REG_TXUC, 48,
+   "UFS_DBG_RD_REG_TXUC ");
+   ufs_qcom_dump_regs(hba, UFS_DBG_RD_REG_RXUC, 27,
+   "UFS_DBG_RD_REG_RXUC ");
+   ufs_qcom_dump_regs(hba, UFS_DBG_RD_REG_DFC, 19,
+   "UFS_DBG_RD_REG_DFC ");
+   ufs_qcom_dump_regs(hba, UFS_DBG_RD_REG_TRLUT, 34,
+   "UFS_DBG_RD_REG_TRLUT ");
+   ufs_qcom_dump_regs(hba, UFS_DBG_RD_REG_TMRLUT, 9,
+   "UFS_DBG_RD_REG_TMRLUT ");
+}
+
+static void ufs_qcom_dump_dbg_regs(struct ufs_hba *hba)
+{
+   ufs_qcom_dump_regs(hba, REG_UFS_SYS1CLK_1US, 5,
+   "REG_UFS_SYS1CLK_1US ");
+
+   ufs_qcom_print_hw_debug_reg_all(hba);
+}
+
 /**
  * struct ufs_hba_qcom_vops - UFS QCOM specific variant operations
  *
@@ -1000,5 +1052,6 @@ static const struct ufs_hba_variant_ops ufs_hba_qcom_vops 
= {
.pwr_change_notify  = ufs_qcom_pwr_change_notify,
.suspend= ufs_qcom_suspend,
.resume = ufs_qcom_resume,
+   .dbg_register_dump  = ufs_qcom_dump_dbg_regs,
 };
 EXPORT_SYMBOL(ufs_hba_qcom_vops);
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 7697cc6..3ae0b3f 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -45,6 +45,9 @@
 #include "unipro.h"
 #include "ufs-debugfs.h"
 
+#define CREATE_TRACE_POINTS
+#include 
+
 #ifdef CONFIG_DEBUG_FS
 
 static void ufshcd_update_error_stats(struct ufs_hba *hba, int type)
@@ -145,6 +148,8 @@ static inline ufshcd_update_error_stats(struct ufs_hba 
*hba, int type)
_ret = ufshcd_disable_vreg(_dev, _vreg);\
_ret;   \
})
+#define ufshcd_hex_dump(prefix_str, buf, len) \
+print_hex_dump(KERN_ERR, prefix_str, DUMP_PREFIX_OFFSET, 16, 4, buf, len, 
false)
 
 static u32 ufs_query_desc_max_size[] = {
QUERY_DESC_DEVICE_MAX_SIZE,
@@ -272,6 +277,151 @@ static inline void ufshcd_disable_irq(struct ufs_hba *hba)
}
 }
 
+#ifdef CONFIG_TRACEPOINTS
+static void ufshcd_add_command_trace(struct ufs_hba *hba,
+   unsigned int tag, const char *str)
+{
+   sector_t lba = -1;
+   u8 opcode = 0;
+   u32 intr, doorbell;
+   

[PATCH v5 3/3] scsi: ufs: add trace events and dump prints for debug

2015-03-10 Thread Gilad Broner
Add trace events to driver to allow monitoring and profilig
of activities such as PM suspend/resume, hibernate enter/exit,
clock gating and clock scaling up/down.
In addition, add UFS host controller register dumps to provide
detailed information in case of errors to assist in analysis
of issues.

Signed-off-by: Dolev Raviv dra...@codeaurora.org
Signed-off-by: Subhash Jadavani subha...@codeaurora.org
Signed-off-by: Lee Susman lsus...@codeaurora.org
Signed-off-by: Sujit Reddy Thumma sthu...@codeaurora.org
Signed-off-by: Yaniv Gardi yga...@codeaurora.org
---
 drivers/scsi/ufs/ufs-qcom.c |  53 +
 drivers/scsi/ufs/ufshcd.c   | 511 +---
 drivers/scsi/ufs/ufshcd.h   |  49 -
 drivers/scsi/ufs/ufshci.h   |   1 +
 include/trace/events/ufs.h  | 227 
 5 files changed, 804 insertions(+), 37 deletions(-)
 create mode 100644 include/trace/events/ufs.h

diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c
index 9217af9..9fe675d 100644
--- a/drivers/scsi/ufs/ufs-qcom.c
+++ b/drivers/scsi/ufs/ufs-qcom.c
@@ -30,6 +30,14 @@ static int ufs_qcom_get_bus_vote(struct ufs_qcom_host *host,
const char *speed_mode);
 static int ufs_qcom_set_bus_vote(struct ufs_qcom_host *host, int vote);
 
+static void ufs_qcom_dump_regs(struct ufs_hba *hba, int offset, int len,
+   char *prefix)
+{
+   print_hex_dump(KERN_ERR, prefix,
+   len  4 ? DUMP_PREFIX_OFFSET : DUMP_PREFIX_NONE,
+   16, 4, hba-mmio_base + offset, len * 4, false);
+}
+
 static int ufs_qcom_get_connected_tx_lanes(struct ufs_hba *hba, u32 *tx_lanes)
 {
int err = 0;
@@ -983,6 +991,50 @@ void ufs_qcom_clk_scale_notify(struct ufs_hba *hba)
dev_req_params-hs_rate);
 }
 
+static void ufs_qcom_print_hw_debug_reg_all(struct ufs_hba *hba)
+{
+   u32 reg;
+
+   ufs_qcom_dump_regs(hba, UFS_UFS_DBG_RD_REG_OCSC, 44,
+   UFS_UFS_DBG_RD_REG_OCSC );
+
+   reg = ufshcd_readl(hba, REG_UFS_CFG1);
+   reg |= UFS_BIT(17);
+   ufshcd_writel(hba, reg, REG_UFS_CFG1);
+
+   ufs_qcom_dump_regs(hba, UFS_UFS_DBG_RD_EDTL_RAM, 32,
+   UFS_UFS_DBG_RD_EDTL_RAM );
+   ufs_qcom_dump_regs(hba, UFS_UFS_DBG_RD_DESC_RAM, 128,
+   UFS_UFS_DBG_RD_DESC_RAM );
+   ufs_qcom_dump_regs(hba, UFS_UFS_DBG_RD_PRDT_RAM, 64,
+   UFS_UFS_DBG_RD_PRDT_RAM );
+
+   ufshcd_writel(hba, (reg  ~UFS_BIT(17)), REG_UFS_CFG1);
+
+   ufs_qcom_dump_regs(hba, UFS_DBG_RD_REG_UAWM, 4,
+   UFS_DBG_RD_REG_UAWM );
+   ufs_qcom_dump_regs(hba, UFS_DBG_RD_REG_UARM, 4,
+   UFS_DBG_RD_REG_UARM );
+   ufs_qcom_dump_regs(hba, UFS_DBG_RD_REG_TXUC, 48,
+   UFS_DBG_RD_REG_TXUC );
+   ufs_qcom_dump_regs(hba, UFS_DBG_RD_REG_RXUC, 27,
+   UFS_DBG_RD_REG_RXUC );
+   ufs_qcom_dump_regs(hba, UFS_DBG_RD_REG_DFC, 19,
+   UFS_DBG_RD_REG_DFC );
+   ufs_qcom_dump_regs(hba, UFS_DBG_RD_REG_TRLUT, 34,
+   UFS_DBG_RD_REG_TRLUT );
+   ufs_qcom_dump_regs(hba, UFS_DBG_RD_REG_TMRLUT, 9,
+   UFS_DBG_RD_REG_TMRLUT );
+}
+
+static void ufs_qcom_dump_dbg_regs(struct ufs_hba *hba)
+{
+   ufs_qcom_dump_regs(hba, REG_UFS_SYS1CLK_1US, 5,
+   REG_UFS_SYS1CLK_1US );
+
+   ufs_qcom_print_hw_debug_reg_all(hba);
+}
+
 /**
  * struct ufs_hba_qcom_vops - UFS QCOM specific variant operations
  *
@@ -1000,5 +1052,6 @@ static const struct ufs_hba_variant_ops ufs_hba_qcom_vops 
= {
.pwr_change_notify  = ufs_qcom_pwr_change_notify,
.suspend= ufs_qcom_suspend,
.resume = ufs_qcom_resume,
+   .dbg_register_dump  = ufs_qcom_dump_dbg_regs,
 };
 EXPORT_SYMBOL(ufs_hba_qcom_vops);
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 7697cc6..3ae0b3f 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -45,6 +45,9 @@
 #include unipro.h
 #include ufs-debugfs.h
 
+#define CREATE_TRACE_POINTS
+#include trace/events/ufs.h
+
 #ifdef CONFIG_DEBUG_FS
 
 static void ufshcd_update_error_stats(struct ufs_hba *hba, int type)
@@ -145,6 +148,8 @@ static inline ufshcd_update_error_stats(struct ufs_hba 
*hba, int type)
_ret = ufshcd_disable_vreg(_dev, _vreg);\
_ret;   \
})
+#define ufshcd_hex_dump(prefix_str, buf, len) \
+print_hex_dump(KERN_ERR, prefix_str, DUMP_PREFIX_OFFSET, 16, 4, buf, len, 
false)
 
 static u32 ufs_query_desc_max_size[] = {
QUERY_DESC_DEVICE_MAX_SIZE,
@@ -272,6 +277,151 @@ static inline void ufshcd_disable_irq(struct ufs_hba *hba)
}
 }
 
+#ifdef CONFIG_TRACEPOINTS
+static void ufshcd_add_command_trace(struct ufs_hba *hba,
+   unsigned int tag, const char 

Re: [PATCH v5 3/3] scsi: ufs: add trace events and dump prints for debug

2015-03-10 Thread Steven Rostedt
On Tue, 10 Mar 2015 13:47:15 +0200
Gilad Broner gbro...@codeaurora.org wrote:


 +++ b/include/trace/events/ufs.h
 @@ -0,0 +1,227 @@
 +/*
 + * Copyright (c) 2013-2015, 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
 +
 +TRACE_EVENT(ufshcd_clk_gating,
 +
 + 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: gating state changed to %s,
 + __get_str(dev_name), __get_str(state))
 +);

This and the auto_bkops_state is pretty much the same. Can't you use
the same TP_printk() and just have a DECLARE_EVENT_CLASS? The trace
point name is printed with the event to see different events.

At least use DEFINE_EVENT_PRINT() that lets you override a EVENT_CLASS
TP_printk(). This saves memory.

-- Steve


 +
 +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))
 +);
 +
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/