Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5d3261c4 authored by Mayank Rana's avatar Mayank Rana
Browse files

dwc3: Separate out debug events for each DWC instance



Currently if there are multiple dwc3 instances, all debug events
are logged in same debug buffer. Hence create separate debug buffer
with each DWC instance as well start using IPC logging instead of
local buffer.

CRs-Fixed: 1040809
Change-Id: I9aee21a99f5bcd0e82e81092c05bc2238863f5e4
Signed-off-by: default avatarMayank Rana <mrana@codeaurora.org>
parent e99d73e0
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -449,6 +449,9 @@ enum event_buf_type {
	EVT_BUF_TYPE_GSI
};

#define DWC_CTRL_COUNT	10
#define NUM_LOG_PAGES	12

/**
 * struct dwc3_event_buffer - Software event buffer representation
 * @buf: _THE_ buffer
@@ -828,6 +831,7 @@ struct dwc3_scratchpad_array {
 * @bh_dbg_index: index for capturing bh_completion_time and bh_handled_evt_cnt
 * @wait_linkstate: waitqueue for waiting LINK to move into required state
 * @vbus_draw: current to be drawn from USB
 * @dwc_ipc_log_ctxt: dwc3 ipa log context
 */
struct dwc3 {
	struct usb_ctrlrequest	*ctrl_req;
@@ -979,6 +983,7 @@ struct dwc3 {
	unsigned                irq_dbg_index;

	wait_queue_head_t	wait_linkstate;
	void			*dwc_ipc_log_ctxt;
};

/* -------------------------------------------------------------------------- */
+37 −15
Original line number Diff line number Diff line
@@ -21,6 +21,28 @@

#include "core.h"

/*
 * NOTE: Make sure to have dwc as local variable in function before using
 * below macros.
 */
#define dbg_event(ep_num, name, status) \
	dwc3_dbg_print(dwc, ep_num, name, status, "")

#define dbg_print(ep_num, name, status, extra) \
	dwc3_dbg_print(dwc, ep_num, name, status, extra)

#define dbg_print_reg(name, reg) \
	dwc3_dbg_print_reg(dwc, name, reg)

#define dbg_done(ep_num, count, status) \
	dwc3_dbg_done(dwc, ep_num, count, status)

#define dbg_queue(ep_num, req, status) \
	dwc3_dbg_queue(dwc, ep_num, req, status)

#define dbg_setup(ep_num, req) \
	dwc3_dbg_setup(dwc, ep_num, req)

/**
 * dwc3_gadget_ep_cmd_string - returns endpoint command string
 * @cmd: command code
@@ -217,28 +239,28 @@ static inline const char *dwc3_gadget_event_type_string(u8 event)
void dwc3_trace(void (*trace)(struct va_format *), const char *fmt, ...);

#ifdef CONFIG_DEBUG_FS
extern void dbg_event(u8, const char*, int);
extern void dbg_print(u8, const char*, int, const char*);
extern void dbg_done(u8, const u32, int);
extern void dbg_queue(u8, const struct usb_request*, int);
extern void dbg_setup(u8, const struct usb_ctrlrequest*);
extern void dwc3_dbg_print(struct dwc3 *, u8, const char*, int, const char*);
extern void dwc3_dbg_done(struct dwc3 *, u8, const u32, int);
extern void dwc3_dbg_queue(struct dwc3 *, u8, const struct usb_request*, int);
extern void dwc3_dbg_setup(struct dwc3 *, u8, const struct usb_ctrlrequest*);
extern int dwc3_debugfs_init(struct dwc3 *);
extern void dwc3_debugfs_exit(struct dwc3 *);
extern void dbg_print_reg(const char *name, int reg);
extern void dwc3_dbg_print_reg(struct dwc3 *, const char *name, int reg);
#else
static inline void dbg_event(u8 ep_num, const char *name, int status)
{  }
static inline void dbg_print(u8 ep_num, const char *name, int status,
			     const char *extra)
static inline void dwc3_dbg_print(struct dwc3 *dwc, u8 ep_num, const char *name,
		int status, const char *extra)
{  }
static inline void dbg_done(u8 ep_num, const u32 count, int status)
static inline void dwc3_dbg_done(struct dwc3 *dwc, u8 ep_num,
		const u32 count, int status)
{  }
static inline void dbg_queue(u8 ep_num, const struct usb_request *req,
			     int status)
static inline void dwc3_dbg_queue(struct dwc3 *dwc, u8 ep_num,
		const struct usb_request *req, int status)
{  }
static inline void dbg_setup(u8 ep_num, const struct usb_ctrlrequest *req)
static inline void dwc3_dbg_setup(struct dwc3 *dwc, u8 ep_num,
		const struct usb_ctrlrequest *req)
{  }
static inline void dbg_print_reg(const char *name, int reg)
static inline void dwc3_dbg_print_reg(struct dwc3 *dwc, const char *name,
				int reg)
{  }
static inline int dwc3_debugfs_init(struct dwc3 *d)
{  return 0;  }
+57 −182
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
#include <linux/uaccess.h>

#include <linux/usb/ch9.h>
#include <linux/ipc_logging.h>

#include "core.h"
#include "gadget.h"
@@ -779,54 +780,7 @@ module_param(ep_addr_rxdbg_mask, uint, S_IRUGO | S_IWUSR);
static unsigned int ep_addr_txdbg_mask = 1;
module_param(ep_addr_txdbg_mask, uint, S_IRUGO | S_IWUSR);

/* Maximum debug message length */
#define DBG_DATA_MSG   64UL

/* Maximum number of messages */
#define DBG_DATA_MAX   2048UL

static struct {
	char     (buf[DBG_DATA_MAX])[DBG_DATA_MSG];   /* buffer */
	unsigned idx;   /* index */
	unsigned tty;   /* print to console? */
	rwlock_t lck;   /* lock */
} dbg_dwc3_data = {
	.idx = 0,
	.tty = 0,
	.lck = __RW_LOCK_UNLOCKED(lck)
};

/**
 * dbg_dec: decrements debug event index
 * @idx: buffer index
 */
static inline void __maybe_unused dbg_dec(unsigned *idx)
{
	*idx = (*idx - 1) % DBG_DATA_MAX;
}

/**
 * dbg_inc: increments debug event index
 * @idx: buffer index
 */
static inline void dbg_inc(unsigned *idx)
{
	*idx = (*idx + 1) % DBG_DATA_MAX;
}

#define TIME_BUF_LEN  20
/*get_timestamp - returns time of day in us */
static char *get_timestamp(char *tbuf)
{
	unsigned long long t;
	unsigned long nanosec_rem;

	t = cpu_clock(smp_processor_id());
	nanosec_rem = do_div(t, 1000000000)/1000;
	scnprintf(tbuf, TIME_BUF_LEN, "[%5lu.%06lu] ", (unsigned long)t,
		nanosec_rem);
	return tbuf;
}
static struct dwc3 *dbg_dwc3_data[DWC_CTRL_COUNT];

static int allow_dbg_print(u8 ep_num)
{
@@ -849,190 +803,95 @@ static int allow_dbg_print(u8 ep_num)
}

/**
 * dbg_print:  prints the common part of the event
 * dwc3_dbg_print:  prints the common part of the event
 * @addr:   endpoint address
 * @name:   event name
 * @status: status
 * @extra:  extra information
 * @dwc3: pointer to struct dwc3
 */
void dbg_print(u8 ep_num, const char *name, int status, const char *extra)
void dwc3_dbg_print(struct dwc3 *dwc, u8 ep_num, const char *name,
			int status, const char *extra)
{
	unsigned long flags;
	char tbuf[TIME_BUF_LEN];

	if (!allow_dbg_print(ep_num))
		return;

	write_lock_irqsave(&dbg_dwc3_data.lck, flags);

	scnprintf(dbg_dwc3_data.buf[dbg_dwc3_data.idx], DBG_DATA_MSG,
		  "%s\t? %02X %-12.12s %4i ?\t%s\n",
		  get_timestamp(tbuf), ep_num, name, status, extra);

	dbg_inc(&dbg_dwc3_data.idx);

	write_unlock_irqrestore(&dbg_dwc3_data.lck, flags);

	if (dbg_dwc3_data.tty != 0)
		pr_notice("%s\t? %02X %-7.7s %4i ?\t%s\n",
			  get_timestamp(tbuf), ep_num, name, status, extra);
}

/**
 * dbg_done: prints a DONE event
 * @addr:   endpoint address
 * @td:     transfer descriptor
 * @status: status
 */
void dbg_done(u8 ep_num, const u32 count, int status)
{
	char msg[DBG_DATA_MSG];

	if (!allow_dbg_print(ep_num))
	if (name == NULL)
		return;

	scnprintf(msg, sizeof(msg), "%d", count);
	dbg_print(ep_num, "DONE", status, msg);
	ipc_log_string(dwc->dwc_ipc_log_ctxt, "%02X %-12.12s %4i ?\t%s",
			ep_num, name, status, extra);
}

/**
 * dbg_event: prints a generic event
 * dwc3_dbg_done: prints a DONE event
 * @addr:   endpoint address
 * @name:   event name
 * @td:     transfer descriptor
 * @status: status
 * @dwc3: pointer to struct dwc3
 */
void dbg_event(u8 ep_num, const char *name, int status)
void dwc3_dbg_done(struct dwc3 *dwc, u8 ep_num,
		const u32 count, int status)
{
	if (!allow_dbg_print(ep_num))
		return;

	if (name != NULL)
		dbg_print(ep_num, name, status, "");
	ipc_log_string(dwc->dwc_ipc_log_ctxt, "%02X %-12.12s %4i ?\t%d",
			ep_num, "DONE", status, count);
}

/*
 * dbg_queue: prints a QUEUE event
 * dwc3_dbg_queue: prints a QUEUE event
 * @addr:   endpoint address
 * @req:    USB request
 * @status: status
 */
void dbg_queue(u8 ep_num, const struct usb_request *req, int status)
void dwc3_dbg_queue(struct dwc3 *dwc, u8 ep_num,
		const struct usb_request *req, int status)
{
	char msg[DBG_DATA_MSG];

	if (!allow_dbg_print(ep_num))
		return;

	if (req != NULL) {
		scnprintf(msg, sizeof(msg),
			  "%d %d", !req->no_interrupt, req->length);
		dbg_print(ep_num, "QUEUE", status, msg);
		ipc_log_string(dwc->dwc_ipc_log_ctxt,
			"%02X %-12.12s %4i ?\t%d %d", ep_num, "QUEUE", status,
			!req->no_interrupt, req->length);
	}
}

/**
 * dbg_setup: prints a SETUP event
 * dwc3_dbg_setup: prints a SETUP event
 * @addr: endpoint address
 * @req:  setup request
 */
void dbg_setup(u8 ep_num, const struct usb_ctrlrequest *req)
void dwc3_dbg_setup(struct dwc3 *dwc, u8 ep_num,
		const struct usb_ctrlrequest *req)
{
	char msg[DBG_DATA_MSG];

	if (!allow_dbg_print(ep_num))
		return;

	if (req != NULL) {
		scnprintf(msg, sizeof(msg),
			  "%02X %02X %04X %04X %d", req->bRequestType,
		ipc_log_string(dwc->dwc_ipc_log_ctxt,
			"%02X %-12.12s ?\t%02X %02X %04X %04X %d",
			ep_num, "SETUP", req->bRequestType,
			req->bRequest, le16_to_cpu(req->wValue),
			le16_to_cpu(req->wIndex), le16_to_cpu(req->wLength));
		dbg_print(ep_num, "SETUP", 0, msg);
	}
}

/**
 * dbg_print_reg: prints a reg value
 * dwc3_dbg_print_reg: prints a reg value
 * @name:   reg name
 * @reg: reg value to be printed
 */
void dbg_print_reg(const char *name, int reg)
void dwc3_dbg_print_reg(struct dwc3 *dwc, const char *name, int reg)
{
	unsigned long flags;

	write_lock_irqsave(&dbg_dwc3_data.lck, flags);

	scnprintf(dbg_dwc3_data.buf[dbg_dwc3_data.idx], DBG_DATA_MSG,
		  "%s = 0x%08x\n", name, reg);

	dbg_inc(&dbg_dwc3_data.idx);

	write_unlock_irqrestore(&dbg_dwc3_data.lck, flags);

	if (dbg_dwc3_data.tty != 0)
		pr_notice("%s = 0x%08x\n", name, reg);
}

/**
 * store_events: configure if events are going to be also printed to console
 *
 */
static ssize_t dwc3_store_events(struct file *file,
			    const char __user *buf, size_t count, loff_t *ppos)
{
	unsigned tty;

	if (buf == NULL) {
		pr_err("[%s] EINVAL\n", __func__);
		goto done;
	}

	if (sscanf(buf, "%u", &tty) != 1 || tty > 1) {
		pr_err("<1|0>: enable|disable console log\n");
		goto done;
	}

	dbg_dwc3_data.tty = tty;
	pr_info("tty = %u", dbg_dwc3_data.tty);

 done:
	return count;
}

static int dwc3_gadget_data_events_show(struct seq_file *s, void *unused)
{
	unsigned long	flags;
	unsigned	i;

	read_lock_irqsave(&dbg_dwc3_data.lck, flags);

	i = dbg_dwc3_data.idx;
	if (strnlen(dbg_dwc3_data.buf[i], DBG_DATA_MSG))
		seq_printf(s, "%s\n", dbg_dwc3_data.buf[i]);
	for (dbg_inc(&i); i != dbg_dwc3_data.idx; dbg_inc(&i)) {
		if (!strnlen(dbg_dwc3_data.buf[i], DBG_DATA_MSG))
			continue;
		seq_printf(s, "%s\n", dbg_dwc3_data.buf[i]);
	}

	read_unlock_irqrestore(&dbg_dwc3_data.lck, flags);
	if (name == NULL)
		return;

	return 0;
	ipc_log_string(dwc->dwc_ipc_log_ctxt, "%s = 0x%08x", name, reg);
}

static int dwc3_gadget_data_events_open(struct inode *inode, struct file *f)
{
	return single_open(f, dwc3_gadget_data_events_show, inode->i_private);
}

const struct file_operations dwc3_gadget_dbg_data_fops = {
	.open			= dwc3_gadget_data_events_open,
	.read			= seq_read,
	.write			= dwc3_store_events,
	.llseek			= seq_lseek,
	.release		= single_release,
};

static ssize_t dwc3_store_int_events(struct file *file,
			const char __user *ubuf, size_t count, loff_t *ppos)
{
@@ -1202,12 +1061,20 @@ const struct file_operations dwc3_gadget_dbg_events_fops = {
	.release	= single_release,
};

static int count;
int dwc3_debugfs_init(struct dwc3 *dwc)
{
	struct dentry		*root;
	struct dentry		*file;
	int			ret;

	if (count >= DWC_CTRL_COUNT) {
		dev_err(dwc->dev, "Err dwc instance %d >= %d available\n",
				count, DWC_CTRL_COUNT);
		ret = -EINVAL;
		return ret;
	}

	root = debugfs_create_dir(dev_name(dwc->dev), NULL);
	if (!root) {
		ret = -ENOMEM;
@@ -1279,23 +1146,27 @@ int dwc3_debugfs_init(struct dwc3 *dwc)
		goto err1;
	}

	file = debugfs_create_file("events", S_IRUGO | S_IWUSR, root,
			dwc, &dwc3_gadget_dbg_data_fops);
	file = debugfs_create_file("int_events", S_IRUGO | S_IWUSR, root,
			dwc, &dwc3_gadget_dbg_events_fops);
	if (!file) {
		ret = -ENOMEM;
		goto err1;
	}

	file = debugfs_create_file("int_events", S_IRUGO | S_IWUSR, root,
			dwc, &dwc3_gadget_dbg_events_fops);
	if (!file) {
		ret = -ENOMEM;
	dwc->dwc_ipc_log_ctxt = ipc_log_context_create(NUM_LOG_PAGES,
					dev_name(dwc->dev), 0);
	if (!dwc->dwc_ipc_log_ctxt) {
		dev_err(dwc->dev, "Error getting ipc_log_ctxt\n");
		goto err1;
	}

	dbg_dwc3_data[count] = dwc;
	count++;
	return 0;

err1:
	kfree(dwc->regset);
	dwc->regset = NULL;
	debugfs_remove_recursive(root);

err0:
@@ -1306,4 +1177,8 @@ void dwc3_debugfs_exit(struct dwc3 *dwc)
{
	debugfs_remove_recursive(dwc->root);
	dwc->root = NULL;
	kfree(dwc->regset);
	dwc->regset = NULL;
	ipc_log_context_destroy(dwc->dwc_ipc_log_ctxt);
	dwc->dwc_ipc_log_ctxt = NULL;
}
+10 −1
Original line number Diff line number Diff line
@@ -3060,6 +3060,7 @@ static int dwc3_msm_remove_children(struct device *dev, void *data)
static int dwc3_msm_remove(struct platform_device *pdev)
{
	struct dwc3_msm	*mdwc = platform_get_drvdata(pdev);
	struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3);
	int ret_pm;

	if (cpu_to_affin)
@@ -3089,10 +3090,11 @@ static int dwc3_msm_remove(struct platform_device *pdev)
		power_supply_unregister(&mdwc->usb_psy);
	if (mdwc->hs_phy)
		mdwc->hs_phy->flags &= ~PHY_HOST_MODE;

	dbg_event(0xFF, "Remov put", 0);
	platform_device_put(mdwc->dwc3);
	device_for_each_child(&pdev->dev, NULL, dwc3_msm_remove_children);

	dbg_event(0xFF, "Remov put", 0);
	pm_runtime_disable(mdwc->dev);
	pm_runtime_barrier(mdwc->dev);
	pm_runtime_put_sync(mdwc->dev);
@@ -3384,6 +3386,7 @@ psy_error:
static void dwc3_check_float_lines(struct dwc3_msm *mdwc)
{
	int dpdm;
	struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3);

	dev_dbg(mdwc->dev, "%s: Check linestate\n", __func__);
	dwc3_msm_gadget_vbus_draw(mdwc, 0);
@@ -3740,6 +3743,7 @@ static int dwc3_msm_pm_suspend(struct device *dev)
static int dwc3_msm_pm_resume(struct device *dev)
{
	struct dwc3_msm *mdwc = dev_get_drvdata(dev);
	struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3);

	dev_dbg(dev, "dwc3-msm PM resume\n");

@@ -3759,6 +3763,9 @@ static int dwc3_msm_pm_resume(struct device *dev)
#ifdef CONFIG_PM_RUNTIME
static int dwc3_msm_runtime_idle(struct device *dev)
{
	struct dwc3_msm *mdwc = dev_get_drvdata(dev);
	struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3);

	dev_dbg(dev, "DWC3-msm runtime idle\n");
	dbg_event(0xFF, "RT Idle", 0);

@@ -3768,6 +3775,7 @@ static int dwc3_msm_runtime_idle(struct device *dev)
static int dwc3_msm_runtime_suspend(struct device *dev)
{
	struct dwc3_msm *mdwc = dev_get_drvdata(dev);
	struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3);

	dev_dbg(dev, "DWC3-msm runtime suspend\n");
	dbg_event(0xFF, "RT Sus", 0);
@@ -3778,6 +3786,7 @@ static int dwc3_msm_runtime_suspend(struct device *dev)
static int dwc3_msm_runtime_resume(struct device *dev)
{
	struct dwc3_msm *mdwc = dev_get_drvdata(dev);
	struct dwc3 *dwc = platform_get_drvdata(mdwc->dwc3);

	dev_dbg(dev, "DWC3-msm runtime resume\n");
	dbg_event(0xFF, "RT Res", 0);
+1 −0
Original line number Diff line number Diff line
@@ -927,6 +927,7 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep, bool starting)
	unsigned int		last_one = 0;
	int			maxpkt_size;
	bool			isoc;
	struct dwc3		*dwc = dep->dwc;

	maxpkt_size = usb_endpoint_maxp(dep->endpoint.desc);
	isoc = usb_endpoint_xfer_isoc(dep->endpoint.desc);