162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (c) 2001-2002 by David Brownell
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci/* this file is part of ehci-hcd.c */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#ifdef CONFIG_DYNAMIC_DEBUG
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci/*
1162306a36Sopenharmony_ci * check the values in the HCSPARAMS register
1262306a36Sopenharmony_ci * (host controller _Structural_ parameters)
1362306a36Sopenharmony_ci * see EHCI spec, Table 2-4 for each value
1462306a36Sopenharmony_ci */
1562306a36Sopenharmony_cistatic void dbg_hcs_params(struct ehci_hcd *ehci, char *label)
1662306a36Sopenharmony_ci{
1762306a36Sopenharmony_ci	u32	params = ehci_readl(ehci, &ehci->caps->hcs_params);
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci	ehci_dbg(ehci,
2062306a36Sopenharmony_ci		"%s hcs_params 0x%x dbg=%d%s cc=%d pcc=%d%s%s ports=%d\n",
2162306a36Sopenharmony_ci		label, params,
2262306a36Sopenharmony_ci		HCS_DEBUG_PORT(params),
2362306a36Sopenharmony_ci		HCS_INDICATOR(params) ? " ind" : "",
2462306a36Sopenharmony_ci		HCS_N_CC(params),
2562306a36Sopenharmony_ci		HCS_N_PCC(params),
2662306a36Sopenharmony_ci		HCS_PORTROUTED(params) ? "" : " ordered",
2762306a36Sopenharmony_ci		HCS_PPC(params) ? "" : " !ppc",
2862306a36Sopenharmony_ci		HCS_N_PORTS(params));
2962306a36Sopenharmony_ci	/* Port routing, per EHCI 0.95 Spec, Section 2.2.5 */
3062306a36Sopenharmony_ci	if (HCS_PORTROUTED(params)) {
3162306a36Sopenharmony_ci		int i;
3262306a36Sopenharmony_ci		char buf[46], tmp[7], byte;
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci		buf[0] = 0;
3562306a36Sopenharmony_ci		for (i = 0; i < HCS_N_PORTS(params); i++) {
3662306a36Sopenharmony_ci			/* FIXME MIPS won't readb() ... */
3762306a36Sopenharmony_ci			byte = readb(&ehci->caps->portroute[(i >> 1)]);
3862306a36Sopenharmony_ci			sprintf(tmp, "%d ",
3962306a36Sopenharmony_ci				(i & 0x1) ? byte & 0xf : (byte >> 4) & 0xf);
4062306a36Sopenharmony_ci			strcat(buf, tmp);
4162306a36Sopenharmony_ci		}
4262306a36Sopenharmony_ci		ehci_dbg(ehci, "%s portroute %s\n", label, buf);
4362306a36Sopenharmony_ci	}
4462306a36Sopenharmony_ci}
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci/*
4762306a36Sopenharmony_ci * check the values in the HCCPARAMS register
4862306a36Sopenharmony_ci * (host controller _Capability_ parameters)
4962306a36Sopenharmony_ci * see EHCI Spec, Table 2-5 for each value
5062306a36Sopenharmony_ci */
5162306a36Sopenharmony_cistatic void dbg_hcc_params(struct ehci_hcd *ehci, char *label)
5262306a36Sopenharmony_ci{
5362306a36Sopenharmony_ci	u32	params = ehci_readl(ehci, &ehci->caps->hcc_params);
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci	if (HCC_ISOC_CACHE(params)) {
5662306a36Sopenharmony_ci		ehci_dbg(ehci,
5762306a36Sopenharmony_ci			"%s hcc_params %04x caching frame %s%s%s\n",
5862306a36Sopenharmony_ci			label, params,
5962306a36Sopenharmony_ci			HCC_PGM_FRAMELISTLEN(params) ? "256/512/1024" : "1024",
6062306a36Sopenharmony_ci			HCC_CANPARK(params) ? " park" : "",
6162306a36Sopenharmony_ci			HCC_64BIT_ADDR(params) ? " 64 bit addr" : "");
6262306a36Sopenharmony_ci	} else {
6362306a36Sopenharmony_ci		ehci_dbg(ehci,
6462306a36Sopenharmony_ci			"%s hcc_params %04x thresh %d uframes %s%s%s%s%s%s%s\n",
6562306a36Sopenharmony_ci			label,
6662306a36Sopenharmony_ci			params,
6762306a36Sopenharmony_ci			HCC_ISOC_THRES(params),
6862306a36Sopenharmony_ci			HCC_PGM_FRAMELISTLEN(params) ? "256/512/1024" : "1024",
6962306a36Sopenharmony_ci			HCC_CANPARK(params) ? " park" : "",
7062306a36Sopenharmony_ci			HCC_64BIT_ADDR(params) ? " 64 bit addr" : "",
7162306a36Sopenharmony_ci			HCC_LPM(params) ? " LPM" : "",
7262306a36Sopenharmony_ci			HCC_PER_PORT_CHANGE_EVENT(params) ? " ppce" : "",
7362306a36Sopenharmony_ci			HCC_HW_PREFETCH(params) ? " hw prefetch" : "",
7462306a36Sopenharmony_ci			HCC_32FRAME_PERIODIC_LIST(params) ?
7562306a36Sopenharmony_ci				" 32 periodic list" : "");
7662306a36Sopenharmony_ci	}
7762306a36Sopenharmony_ci}
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_cistatic void __maybe_unused
8062306a36Sopenharmony_cidbg_qtd(const char *label, struct ehci_hcd *ehci, struct ehci_qtd *qtd)
8162306a36Sopenharmony_ci{
8262306a36Sopenharmony_ci	ehci_dbg(ehci, "%s td %p n%08x %08x t%08x p0=%08x\n", label, qtd,
8362306a36Sopenharmony_ci		hc32_to_cpup(ehci, &qtd->hw_next),
8462306a36Sopenharmony_ci		hc32_to_cpup(ehci, &qtd->hw_alt_next),
8562306a36Sopenharmony_ci		hc32_to_cpup(ehci, &qtd->hw_token),
8662306a36Sopenharmony_ci		hc32_to_cpup(ehci, &qtd->hw_buf[0]));
8762306a36Sopenharmony_ci	if (qtd->hw_buf[1])
8862306a36Sopenharmony_ci		ehci_dbg(ehci, "  p1=%08x p2=%08x p3=%08x p4=%08x\n",
8962306a36Sopenharmony_ci			hc32_to_cpup(ehci, &qtd->hw_buf[1]),
9062306a36Sopenharmony_ci			hc32_to_cpup(ehci, &qtd->hw_buf[2]),
9162306a36Sopenharmony_ci			hc32_to_cpup(ehci, &qtd->hw_buf[3]),
9262306a36Sopenharmony_ci			hc32_to_cpup(ehci, &qtd->hw_buf[4]));
9362306a36Sopenharmony_ci}
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_cistatic void __maybe_unused
9662306a36Sopenharmony_cidbg_qh(const char *label, struct ehci_hcd *ehci, struct ehci_qh *qh)
9762306a36Sopenharmony_ci{
9862306a36Sopenharmony_ci	struct ehci_qh_hw *hw = qh->hw;
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci	ehci_dbg(ehci, "%s qh %p n%08x info %x %x qtd %x\n", label,
10162306a36Sopenharmony_ci		qh, hw->hw_next, hw->hw_info1, hw->hw_info2, hw->hw_current);
10262306a36Sopenharmony_ci	dbg_qtd("overlay", ehci, (struct ehci_qtd *) &hw->hw_qtd_next);
10362306a36Sopenharmony_ci}
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_cistatic void __maybe_unused
10662306a36Sopenharmony_cidbg_itd(const char *label, struct ehci_hcd *ehci, struct ehci_itd *itd)
10762306a36Sopenharmony_ci{
10862306a36Sopenharmony_ci	ehci_dbg(ehci, "%s [%d] itd %p, next %08x, urb %p\n",
10962306a36Sopenharmony_ci		label, itd->frame, itd, hc32_to_cpu(ehci, itd->hw_next),
11062306a36Sopenharmony_ci		itd->urb);
11162306a36Sopenharmony_ci	ehci_dbg(ehci,
11262306a36Sopenharmony_ci		"  trans: %08x %08x %08x %08x %08x %08x %08x %08x\n",
11362306a36Sopenharmony_ci		hc32_to_cpu(ehci, itd->hw_transaction[0]),
11462306a36Sopenharmony_ci		hc32_to_cpu(ehci, itd->hw_transaction[1]),
11562306a36Sopenharmony_ci		hc32_to_cpu(ehci, itd->hw_transaction[2]),
11662306a36Sopenharmony_ci		hc32_to_cpu(ehci, itd->hw_transaction[3]),
11762306a36Sopenharmony_ci		hc32_to_cpu(ehci, itd->hw_transaction[4]),
11862306a36Sopenharmony_ci		hc32_to_cpu(ehci, itd->hw_transaction[5]),
11962306a36Sopenharmony_ci		hc32_to_cpu(ehci, itd->hw_transaction[6]),
12062306a36Sopenharmony_ci		hc32_to_cpu(ehci, itd->hw_transaction[7]));
12162306a36Sopenharmony_ci	ehci_dbg(ehci,
12262306a36Sopenharmony_ci		"  buf:   %08x %08x %08x %08x %08x %08x %08x\n",
12362306a36Sopenharmony_ci		hc32_to_cpu(ehci, itd->hw_bufp[0]),
12462306a36Sopenharmony_ci		hc32_to_cpu(ehci, itd->hw_bufp[1]),
12562306a36Sopenharmony_ci		hc32_to_cpu(ehci, itd->hw_bufp[2]),
12662306a36Sopenharmony_ci		hc32_to_cpu(ehci, itd->hw_bufp[3]),
12762306a36Sopenharmony_ci		hc32_to_cpu(ehci, itd->hw_bufp[4]),
12862306a36Sopenharmony_ci		hc32_to_cpu(ehci, itd->hw_bufp[5]),
12962306a36Sopenharmony_ci		hc32_to_cpu(ehci, itd->hw_bufp[6]));
13062306a36Sopenharmony_ci	ehci_dbg(ehci, "  index: %d %d %d %d %d %d %d %d\n",
13162306a36Sopenharmony_ci		itd->index[0], itd->index[1], itd->index[2],
13262306a36Sopenharmony_ci		itd->index[3], itd->index[4], itd->index[5],
13362306a36Sopenharmony_ci		itd->index[6], itd->index[7]);
13462306a36Sopenharmony_ci}
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_cistatic void __maybe_unused
13762306a36Sopenharmony_cidbg_sitd(const char *label, struct ehci_hcd *ehci, struct ehci_sitd *sitd)
13862306a36Sopenharmony_ci{
13962306a36Sopenharmony_ci	ehci_dbg(ehci, "%s [%d] sitd %p, next %08x, urb %p\n",
14062306a36Sopenharmony_ci		label, sitd->frame, sitd, hc32_to_cpu(ehci, sitd->hw_next),
14162306a36Sopenharmony_ci		sitd->urb);
14262306a36Sopenharmony_ci	ehci_dbg(ehci,
14362306a36Sopenharmony_ci		"  addr %08x sched %04x result %08x buf %08x %08x\n",
14462306a36Sopenharmony_ci		hc32_to_cpu(ehci, sitd->hw_fullspeed_ep),
14562306a36Sopenharmony_ci		hc32_to_cpu(ehci, sitd->hw_uframe),
14662306a36Sopenharmony_ci		hc32_to_cpu(ehci, sitd->hw_results),
14762306a36Sopenharmony_ci		hc32_to_cpu(ehci, sitd->hw_buf[0]),
14862306a36Sopenharmony_ci		hc32_to_cpu(ehci, sitd->hw_buf[1]));
14962306a36Sopenharmony_ci}
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_cistatic int __maybe_unused
15262306a36Sopenharmony_cidbg_status_buf(char *buf, unsigned len, const char *label, u32 status)
15362306a36Sopenharmony_ci{
15462306a36Sopenharmony_ci	return scnprintf(buf, len,
15562306a36Sopenharmony_ci		"%s%sstatus %04x%s%s%s%s%s%s%s%s%s%s%s",
15662306a36Sopenharmony_ci		label, label[0] ? " " : "", status,
15762306a36Sopenharmony_ci		(status & STS_PPCE_MASK) ? " PPCE" : "",
15862306a36Sopenharmony_ci		(status & STS_ASS) ? " Async" : "",
15962306a36Sopenharmony_ci		(status & STS_PSS) ? " Periodic" : "",
16062306a36Sopenharmony_ci		(status & STS_RECL) ? " Recl" : "",
16162306a36Sopenharmony_ci		(status & STS_HALT) ? " Halt" : "",
16262306a36Sopenharmony_ci		(status & STS_IAA) ? " IAA" : "",
16362306a36Sopenharmony_ci		(status & STS_FATAL) ? " FATAL" : "",
16462306a36Sopenharmony_ci		(status & STS_FLR) ? " FLR" : "",
16562306a36Sopenharmony_ci		(status & STS_PCD) ? " PCD" : "",
16662306a36Sopenharmony_ci		(status & STS_ERR) ? " ERR" : "",
16762306a36Sopenharmony_ci		(status & STS_INT) ? " INT" : "");
16862306a36Sopenharmony_ci}
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_cistatic int __maybe_unused
17162306a36Sopenharmony_cidbg_intr_buf(char *buf, unsigned len, const char *label, u32 enable)
17262306a36Sopenharmony_ci{
17362306a36Sopenharmony_ci	return scnprintf(buf, len,
17462306a36Sopenharmony_ci		"%s%sintrenable %02x%s%s%s%s%s%s%s",
17562306a36Sopenharmony_ci		label, label[0] ? " " : "", enable,
17662306a36Sopenharmony_ci		(enable & STS_PPCE_MASK) ? " PPCE" : "",
17762306a36Sopenharmony_ci		(enable & STS_IAA) ? " IAA" : "",
17862306a36Sopenharmony_ci		(enable & STS_FATAL) ? " FATAL" : "",
17962306a36Sopenharmony_ci		(enable & STS_FLR) ? " FLR" : "",
18062306a36Sopenharmony_ci		(enable & STS_PCD) ? " PCD" : "",
18162306a36Sopenharmony_ci		(enable & STS_ERR) ? " ERR" : "",
18262306a36Sopenharmony_ci		(enable & STS_INT) ? " INT" : "");
18362306a36Sopenharmony_ci}
18462306a36Sopenharmony_ci
18562306a36Sopenharmony_cistatic const char *const fls_strings[] = { "1024", "512", "256", "??" };
18662306a36Sopenharmony_ci
18762306a36Sopenharmony_cistatic int
18862306a36Sopenharmony_cidbg_command_buf(char *buf, unsigned len, const char *label, u32 command)
18962306a36Sopenharmony_ci{
19062306a36Sopenharmony_ci	return scnprintf(buf, len,
19162306a36Sopenharmony_ci		"%s%scommand %07x %s%s%s%s%s%s=%d ithresh=%d%s%s%s%s "
19262306a36Sopenharmony_ci		"period=%s%s %s",
19362306a36Sopenharmony_ci		label, label[0] ? " " : "", command,
19462306a36Sopenharmony_ci		(command & CMD_HIRD) ? " HIRD" : "",
19562306a36Sopenharmony_ci		(command & CMD_PPCEE) ? " PPCEE" : "",
19662306a36Sopenharmony_ci		(command & CMD_FSP) ? " FSP" : "",
19762306a36Sopenharmony_ci		(command & CMD_ASPE) ? " ASPE" : "",
19862306a36Sopenharmony_ci		(command & CMD_PSPE) ? " PSPE" : "",
19962306a36Sopenharmony_ci		(command & CMD_PARK) ? " park" : "(park)",
20062306a36Sopenharmony_ci		CMD_PARK_CNT(command),
20162306a36Sopenharmony_ci		(command >> 16) & 0x3f,
20262306a36Sopenharmony_ci		(command & CMD_LRESET) ? " LReset" : "",
20362306a36Sopenharmony_ci		(command & CMD_IAAD) ? " IAAD" : "",
20462306a36Sopenharmony_ci		(command & CMD_ASE) ? " Async" : "",
20562306a36Sopenharmony_ci		(command & CMD_PSE) ? " Periodic" : "",
20662306a36Sopenharmony_ci		fls_strings[(command >> 2) & 0x3],
20762306a36Sopenharmony_ci		(command & CMD_RESET) ? " Reset" : "",
20862306a36Sopenharmony_ci		(command & CMD_RUN) ? "RUN" : "HALT");
20962306a36Sopenharmony_ci}
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_cistatic int
21262306a36Sopenharmony_cidbg_port_buf(char *buf, unsigned len, const char *label, int port, u32 status)
21362306a36Sopenharmony_ci{
21462306a36Sopenharmony_ci	char	*sig;
21562306a36Sopenharmony_ci
21662306a36Sopenharmony_ci	/* signaling state */
21762306a36Sopenharmony_ci	switch (status & (3 << 10)) {
21862306a36Sopenharmony_ci	case 0 << 10:
21962306a36Sopenharmony_ci		sig = "se0";
22062306a36Sopenharmony_ci		break;
22162306a36Sopenharmony_ci	case 1 << 10: /* low speed */
22262306a36Sopenharmony_ci		sig = "k";
22362306a36Sopenharmony_ci		break;
22462306a36Sopenharmony_ci	case 2 << 10:
22562306a36Sopenharmony_ci		sig = "j";
22662306a36Sopenharmony_ci		break;
22762306a36Sopenharmony_ci	default:
22862306a36Sopenharmony_ci		sig = "?";
22962306a36Sopenharmony_ci		break;
23062306a36Sopenharmony_ci	}
23162306a36Sopenharmony_ci
23262306a36Sopenharmony_ci	return scnprintf(buf, len,
23362306a36Sopenharmony_ci		"%s%sport:%d status %06x %d %s%s%s%s%s%s "
23462306a36Sopenharmony_ci		"sig=%s%s%s%s%s%s%s%s%s%s%s",
23562306a36Sopenharmony_ci		label, label[0] ? " " : "", port, status,
23662306a36Sopenharmony_ci		status >> 25, /*device address */
23762306a36Sopenharmony_ci		(status & PORT_SSTS) >> 23 == PORTSC_SUSPEND_STS_ACK ?
23862306a36Sopenharmony_ci						" ACK" : "",
23962306a36Sopenharmony_ci		(status & PORT_SSTS) >> 23 == PORTSC_SUSPEND_STS_NYET ?
24062306a36Sopenharmony_ci						" NYET" : "",
24162306a36Sopenharmony_ci		(status & PORT_SSTS) >> 23 == PORTSC_SUSPEND_STS_STALL ?
24262306a36Sopenharmony_ci						" STALL" : "",
24362306a36Sopenharmony_ci		(status & PORT_SSTS) >> 23 == PORTSC_SUSPEND_STS_ERR ?
24462306a36Sopenharmony_ci						" ERR" : "",
24562306a36Sopenharmony_ci		(status & PORT_POWER) ? " POWER" : "",
24662306a36Sopenharmony_ci		(status & PORT_OWNER) ? " OWNER" : "",
24762306a36Sopenharmony_ci		sig,
24862306a36Sopenharmony_ci		(status & PORT_LPM) ? " LPM" : "",
24962306a36Sopenharmony_ci		(status & PORT_RESET) ? " RESET" : "",
25062306a36Sopenharmony_ci		(status & PORT_SUSPEND) ? " SUSPEND" : "",
25162306a36Sopenharmony_ci		(status & PORT_RESUME) ? " RESUME" : "",
25262306a36Sopenharmony_ci		(status & PORT_OCC) ? " OCC" : "",
25362306a36Sopenharmony_ci		(status & PORT_OC) ? " OC" : "",
25462306a36Sopenharmony_ci		(status & PORT_PEC) ? " PEC" : "",
25562306a36Sopenharmony_ci		(status & PORT_PE) ? " PE" : "",
25662306a36Sopenharmony_ci		(status & PORT_CSC) ? " CSC" : "",
25762306a36Sopenharmony_ci		(status & PORT_CONNECT) ? " CONNECT" : "");
25862306a36Sopenharmony_ci}
25962306a36Sopenharmony_ci
26062306a36Sopenharmony_cistatic inline void
26162306a36Sopenharmony_cidbg_status(struct ehci_hcd *ehci, const char *label, u32 status)
26262306a36Sopenharmony_ci{
26362306a36Sopenharmony_ci	char buf[80];
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_ci	dbg_status_buf(buf, sizeof(buf), label, status);
26662306a36Sopenharmony_ci	ehci_dbg(ehci, "%s\n", buf);
26762306a36Sopenharmony_ci}
26862306a36Sopenharmony_ci
26962306a36Sopenharmony_cistatic inline void
27062306a36Sopenharmony_cidbg_cmd(struct ehci_hcd *ehci, const char *label, u32 command)
27162306a36Sopenharmony_ci{
27262306a36Sopenharmony_ci	char buf[80];
27362306a36Sopenharmony_ci
27462306a36Sopenharmony_ci	dbg_command_buf(buf, sizeof(buf), label, command);
27562306a36Sopenharmony_ci	ehci_dbg(ehci, "%s\n", buf);
27662306a36Sopenharmony_ci}
27762306a36Sopenharmony_ci
27862306a36Sopenharmony_cistatic inline void
27962306a36Sopenharmony_cidbg_port(struct ehci_hcd *ehci, const char *label, int port, u32 status)
28062306a36Sopenharmony_ci{
28162306a36Sopenharmony_ci	char buf[80];
28262306a36Sopenharmony_ci
28362306a36Sopenharmony_ci	dbg_port_buf(buf, sizeof(buf), label, port, status);
28462306a36Sopenharmony_ci	ehci_dbg(ehci, "%s\n", buf);
28562306a36Sopenharmony_ci}
28662306a36Sopenharmony_ci
28762306a36Sopenharmony_ci/*-------------------------------------------------------------------------*/
28862306a36Sopenharmony_ci
28962306a36Sopenharmony_ci/* troubleshooting help: expose state in debugfs */
29062306a36Sopenharmony_ci
29162306a36Sopenharmony_cistatic int debug_async_open(struct inode *, struct file *);
29262306a36Sopenharmony_cistatic int debug_bandwidth_open(struct inode *, struct file *);
29362306a36Sopenharmony_cistatic int debug_periodic_open(struct inode *, struct file *);
29462306a36Sopenharmony_cistatic int debug_registers_open(struct inode *, struct file *);
29562306a36Sopenharmony_ci
29662306a36Sopenharmony_cistatic ssize_t debug_output(struct file*, char __user*, size_t, loff_t*);
29762306a36Sopenharmony_cistatic int debug_close(struct inode *, struct file *);
29862306a36Sopenharmony_ci
29962306a36Sopenharmony_cistatic const struct file_operations debug_async_fops = {
30062306a36Sopenharmony_ci	.owner		= THIS_MODULE,
30162306a36Sopenharmony_ci	.open		= debug_async_open,
30262306a36Sopenharmony_ci	.read		= debug_output,
30362306a36Sopenharmony_ci	.release	= debug_close,
30462306a36Sopenharmony_ci	.llseek		= default_llseek,
30562306a36Sopenharmony_ci};
30662306a36Sopenharmony_ci
30762306a36Sopenharmony_cistatic const struct file_operations debug_bandwidth_fops = {
30862306a36Sopenharmony_ci	.owner		= THIS_MODULE,
30962306a36Sopenharmony_ci	.open		= debug_bandwidth_open,
31062306a36Sopenharmony_ci	.read		= debug_output,
31162306a36Sopenharmony_ci	.release	= debug_close,
31262306a36Sopenharmony_ci	.llseek		= default_llseek,
31362306a36Sopenharmony_ci};
31462306a36Sopenharmony_ci
31562306a36Sopenharmony_cistatic const struct file_operations debug_periodic_fops = {
31662306a36Sopenharmony_ci	.owner		= THIS_MODULE,
31762306a36Sopenharmony_ci	.open		= debug_periodic_open,
31862306a36Sopenharmony_ci	.read		= debug_output,
31962306a36Sopenharmony_ci	.release	= debug_close,
32062306a36Sopenharmony_ci	.llseek		= default_llseek,
32162306a36Sopenharmony_ci};
32262306a36Sopenharmony_ci
32362306a36Sopenharmony_cistatic const struct file_operations debug_registers_fops = {
32462306a36Sopenharmony_ci	.owner		= THIS_MODULE,
32562306a36Sopenharmony_ci	.open		= debug_registers_open,
32662306a36Sopenharmony_ci	.read		= debug_output,
32762306a36Sopenharmony_ci	.release	= debug_close,
32862306a36Sopenharmony_ci	.llseek		= default_llseek,
32962306a36Sopenharmony_ci};
33062306a36Sopenharmony_ci
33162306a36Sopenharmony_cistatic struct dentry *ehci_debug_root;
33262306a36Sopenharmony_ci
33362306a36Sopenharmony_cistruct debug_buffer {
33462306a36Sopenharmony_ci	ssize_t (*fill_func)(struct debug_buffer *);	/* fill method */
33562306a36Sopenharmony_ci	struct usb_bus *bus;
33662306a36Sopenharmony_ci	struct mutex mutex;	/* protect filling of buffer */
33762306a36Sopenharmony_ci	size_t count;		/* number of characters filled into buffer */
33862306a36Sopenharmony_ci	char *output_buf;
33962306a36Sopenharmony_ci	size_t alloc_size;
34062306a36Sopenharmony_ci};
34162306a36Sopenharmony_ci
34262306a36Sopenharmony_cistatic inline char speed_char(u32 info1)
34362306a36Sopenharmony_ci{
34462306a36Sopenharmony_ci	switch (info1 & (3 << 12)) {
34562306a36Sopenharmony_ci	case QH_FULL_SPEED:
34662306a36Sopenharmony_ci		return 'f';
34762306a36Sopenharmony_ci	case QH_LOW_SPEED:
34862306a36Sopenharmony_ci		return 'l';
34962306a36Sopenharmony_ci	case QH_HIGH_SPEED:
35062306a36Sopenharmony_ci		return 'h';
35162306a36Sopenharmony_ci	default:
35262306a36Sopenharmony_ci		return '?';
35362306a36Sopenharmony_ci	}
35462306a36Sopenharmony_ci}
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_cistatic inline char token_mark(struct ehci_hcd *ehci, __hc32 token)
35762306a36Sopenharmony_ci{
35862306a36Sopenharmony_ci	__u32 v = hc32_to_cpu(ehci, token);
35962306a36Sopenharmony_ci
36062306a36Sopenharmony_ci	if (v & QTD_STS_ACTIVE)
36162306a36Sopenharmony_ci		return '*';
36262306a36Sopenharmony_ci	if (v & QTD_STS_HALT)
36362306a36Sopenharmony_ci		return '-';
36462306a36Sopenharmony_ci	if (!IS_SHORT_READ(v))
36562306a36Sopenharmony_ci		return ' ';
36662306a36Sopenharmony_ci	/* tries to advance through hw_alt_next */
36762306a36Sopenharmony_ci	return '/';
36862306a36Sopenharmony_ci}
36962306a36Sopenharmony_ci
37062306a36Sopenharmony_cistatic void qh_lines(struct ehci_hcd *ehci, struct ehci_qh *qh,
37162306a36Sopenharmony_ci		char **nextp, unsigned *sizep)
37262306a36Sopenharmony_ci{
37362306a36Sopenharmony_ci	u32			scratch;
37462306a36Sopenharmony_ci	u32			hw_curr;
37562306a36Sopenharmony_ci	struct list_head	*entry;
37662306a36Sopenharmony_ci	struct ehci_qtd		*td;
37762306a36Sopenharmony_ci	unsigned		temp;
37862306a36Sopenharmony_ci	unsigned		size = *sizep;
37962306a36Sopenharmony_ci	char			*next = *nextp;
38062306a36Sopenharmony_ci	char			mark;
38162306a36Sopenharmony_ci	__le32			list_end = EHCI_LIST_END(ehci);
38262306a36Sopenharmony_ci	struct ehci_qh_hw	*hw = qh->hw;
38362306a36Sopenharmony_ci
38462306a36Sopenharmony_ci	if (hw->hw_qtd_next == list_end)	/* NEC does this */
38562306a36Sopenharmony_ci		mark = '@';
38662306a36Sopenharmony_ci	else
38762306a36Sopenharmony_ci		mark = token_mark(ehci, hw->hw_token);
38862306a36Sopenharmony_ci	if (mark == '/') {	/* qh_alt_next controls qh advance? */
38962306a36Sopenharmony_ci		if ((hw->hw_alt_next & QTD_MASK(ehci))
39062306a36Sopenharmony_ci				== ehci->async->hw->hw_alt_next)
39162306a36Sopenharmony_ci			mark = '#';	/* blocked */
39262306a36Sopenharmony_ci		else if (hw->hw_alt_next == list_end)
39362306a36Sopenharmony_ci			mark = '.';	/* use hw_qtd_next */
39462306a36Sopenharmony_ci		/* else alt_next points to some other qtd */
39562306a36Sopenharmony_ci	}
39662306a36Sopenharmony_ci	scratch = hc32_to_cpup(ehci, &hw->hw_info1);
39762306a36Sopenharmony_ci	hw_curr = (mark == '*') ? hc32_to_cpup(ehci, &hw->hw_current) : 0;
39862306a36Sopenharmony_ci	temp = scnprintf(next, size,
39962306a36Sopenharmony_ci			"qh/%p dev%d %cs ep%d %08x %08x (%08x%c %s nak%d)"
40062306a36Sopenharmony_ci			" [cur %08x next %08x buf[0] %08x]",
40162306a36Sopenharmony_ci			qh, scratch & 0x007f,
40262306a36Sopenharmony_ci			speed_char (scratch),
40362306a36Sopenharmony_ci			(scratch >> 8) & 0x000f,
40462306a36Sopenharmony_ci			scratch, hc32_to_cpup(ehci, &hw->hw_info2),
40562306a36Sopenharmony_ci			hc32_to_cpup(ehci, &hw->hw_token), mark,
40662306a36Sopenharmony_ci			(cpu_to_hc32(ehci, QTD_TOGGLE) & hw->hw_token)
40762306a36Sopenharmony_ci				? "data1" : "data0",
40862306a36Sopenharmony_ci			(hc32_to_cpup(ehci, &hw->hw_alt_next) >> 1) & 0x0f,
40962306a36Sopenharmony_ci			hc32_to_cpup(ehci, &hw->hw_current),
41062306a36Sopenharmony_ci			hc32_to_cpup(ehci, &hw->hw_qtd_next),
41162306a36Sopenharmony_ci			hc32_to_cpup(ehci, &hw->hw_buf[0]));
41262306a36Sopenharmony_ci	size -= temp;
41362306a36Sopenharmony_ci	next += temp;
41462306a36Sopenharmony_ci
41562306a36Sopenharmony_ci	/* hc may be modifying the list as we read it ... */
41662306a36Sopenharmony_ci	list_for_each(entry, &qh->qtd_list) {
41762306a36Sopenharmony_ci		char *type;
41862306a36Sopenharmony_ci
41962306a36Sopenharmony_ci		td = list_entry(entry, struct ehci_qtd, qtd_list);
42062306a36Sopenharmony_ci		scratch = hc32_to_cpup(ehci, &td->hw_token);
42162306a36Sopenharmony_ci		mark = ' ';
42262306a36Sopenharmony_ci		if (hw_curr == td->qtd_dma) {
42362306a36Sopenharmony_ci			mark = '*';
42462306a36Sopenharmony_ci		} else if (hw->hw_qtd_next == cpu_to_hc32(ehci, td->qtd_dma)) {
42562306a36Sopenharmony_ci			mark = '+';
42662306a36Sopenharmony_ci		} else if (QTD_LENGTH(scratch)) {
42762306a36Sopenharmony_ci			if (td->hw_alt_next == ehci->async->hw->hw_alt_next)
42862306a36Sopenharmony_ci				mark = '#';
42962306a36Sopenharmony_ci			else if (td->hw_alt_next != list_end)
43062306a36Sopenharmony_ci				mark = '/';
43162306a36Sopenharmony_ci		}
43262306a36Sopenharmony_ci		switch ((scratch >> 8) & 0x03) {
43362306a36Sopenharmony_ci		case 0:
43462306a36Sopenharmony_ci			type = "out";
43562306a36Sopenharmony_ci			break;
43662306a36Sopenharmony_ci		case 1:
43762306a36Sopenharmony_ci			type = "in";
43862306a36Sopenharmony_ci			break;
43962306a36Sopenharmony_ci		case 2:
44062306a36Sopenharmony_ci			type = "setup";
44162306a36Sopenharmony_ci			break;
44262306a36Sopenharmony_ci		default:
44362306a36Sopenharmony_ci			type = "?";
44462306a36Sopenharmony_ci			break;
44562306a36Sopenharmony_ci		}
44662306a36Sopenharmony_ci		temp = scnprintf(next, size,
44762306a36Sopenharmony_ci				"\n\t%p%c%s len=%d %08x urb %p"
44862306a36Sopenharmony_ci				" [td %08x buf[0] %08x]",
44962306a36Sopenharmony_ci				td, mark, type,
45062306a36Sopenharmony_ci				(scratch >> 16) & 0x7fff,
45162306a36Sopenharmony_ci				scratch,
45262306a36Sopenharmony_ci				td->urb,
45362306a36Sopenharmony_ci				(u32) td->qtd_dma,
45462306a36Sopenharmony_ci				hc32_to_cpup(ehci, &td->hw_buf[0]));
45562306a36Sopenharmony_ci		size -= temp;
45662306a36Sopenharmony_ci		next += temp;
45762306a36Sopenharmony_ci		if (temp == size)
45862306a36Sopenharmony_ci			goto done;
45962306a36Sopenharmony_ci	}
46062306a36Sopenharmony_ci
46162306a36Sopenharmony_ci	temp = scnprintf(next, size, "\n");
46262306a36Sopenharmony_ci	size -= temp;
46362306a36Sopenharmony_ci	next += temp;
46462306a36Sopenharmony_ci
46562306a36Sopenharmony_cidone:
46662306a36Sopenharmony_ci	*sizep = size;
46762306a36Sopenharmony_ci	*nextp = next;
46862306a36Sopenharmony_ci}
46962306a36Sopenharmony_ci
47062306a36Sopenharmony_cistatic ssize_t fill_async_buffer(struct debug_buffer *buf)
47162306a36Sopenharmony_ci{
47262306a36Sopenharmony_ci	struct usb_hcd		*hcd;
47362306a36Sopenharmony_ci	struct ehci_hcd		*ehci;
47462306a36Sopenharmony_ci	unsigned long		flags;
47562306a36Sopenharmony_ci	unsigned		temp, size;
47662306a36Sopenharmony_ci	char			*next;
47762306a36Sopenharmony_ci	struct ehci_qh		*qh;
47862306a36Sopenharmony_ci
47962306a36Sopenharmony_ci	hcd = bus_to_hcd(buf->bus);
48062306a36Sopenharmony_ci	ehci = hcd_to_ehci(hcd);
48162306a36Sopenharmony_ci	next = buf->output_buf;
48262306a36Sopenharmony_ci	size = buf->alloc_size;
48362306a36Sopenharmony_ci
48462306a36Sopenharmony_ci	*next = 0;
48562306a36Sopenharmony_ci
48662306a36Sopenharmony_ci	/*
48762306a36Sopenharmony_ci	 * dumps a snapshot of the async schedule.
48862306a36Sopenharmony_ci	 * usually empty except for long-term bulk reads, or head.
48962306a36Sopenharmony_ci	 * one QH per line, and TDs we know about
49062306a36Sopenharmony_ci	 */
49162306a36Sopenharmony_ci	spin_lock_irqsave(&ehci->lock, flags);
49262306a36Sopenharmony_ci	for (qh = ehci->async->qh_next.qh; size > 0 && qh; qh = qh->qh_next.qh)
49362306a36Sopenharmony_ci		qh_lines(ehci, qh, &next, &size);
49462306a36Sopenharmony_ci	if (!list_empty(&ehci->async_unlink) && size > 0) {
49562306a36Sopenharmony_ci		temp = scnprintf(next, size, "\nunlink =\n");
49662306a36Sopenharmony_ci		size -= temp;
49762306a36Sopenharmony_ci		next += temp;
49862306a36Sopenharmony_ci
49962306a36Sopenharmony_ci		list_for_each_entry(qh, &ehci->async_unlink, unlink_node) {
50062306a36Sopenharmony_ci			if (size <= 0)
50162306a36Sopenharmony_ci				break;
50262306a36Sopenharmony_ci			qh_lines(ehci, qh, &next, &size);
50362306a36Sopenharmony_ci		}
50462306a36Sopenharmony_ci	}
50562306a36Sopenharmony_ci	spin_unlock_irqrestore(&ehci->lock, flags);
50662306a36Sopenharmony_ci
50762306a36Sopenharmony_ci	return strlen(buf->output_buf);
50862306a36Sopenharmony_ci}
50962306a36Sopenharmony_ci
51062306a36Sopenharmony_cistatic ssize_t fill_bandwidth_buffer(struct debug_buffer *buf)
51162306a36Sopenharmony_ci{
51262306a36Sopenharmony_ci	struct ehci_hcd		*ehci;
51362306a36Sopenharmony_ci	struct ehci_tt		*tt;
51462306a36Sopenharmony_ci	struct ehci_per_sched	*ps;
51562306a36Sopenharmony_ci	unsigned		temp, size;
51662306a36Sopenharmony_ci	char			*next;
51762306a36Sopenharmony_ci	unsigned		i;
51862306a36Sopenharmony_ci	u8			*bw;
51962306a36Sopenharmony_ci	u16			*bf;
52062306a36Sopenharmony_ci	u8			budget[EHCI_BANDWIDTH_SIZE];
52162306a36Sopenharmony_ci
52262306a36Sopenharmony_ci	ehci = hcd_to_ehci(bus_to_hcd(buf->bus));
52362306a36Sopenharmony_ci	next = buf->output_buf;
52462306a36Sopenharmony_ci	size = buf->alloc_size;
52562306a36Sopenharmony_ci
52662306a36Sopenharmony_ci	*next = 0;
52762306a36Sopenharmony_ci
52862306a36Sopenharmony_ci	spin_lock_irq(&ehci->lock);
52962306a36Sopenharmony_ci
53062306a36Sopenharmony_ci	/* Dump the HS bandwidth table */
53162306a36Sopenharmony_ci	temp = scnprintf(next, size,
53262306a36Sopenharmony_ci			"HS bandwidth allocation (us per microframe)\n");
53362306a36Sopenharmony_ci	size -= temp;
53462306a36Sopenharmony_ci	next += temp;
53562306a36Sopenharmony_ci	for (i = 0; i < EHCI_BANDWIDTH_SIZE; i += 8) {
53662306a36Sopenharmony_ci		bw = &ehci->bandwidth[i];
53762306a36Sopenharmony_ci		temp = scnprintf(next, size,
53862306a36Sopenharmony_ci				"%2u: %4u%4u%4u%4u%4u%4u%4u%4u\n",
53962306a36Sopenharmony_ci				i, bw[0], bw[1], bw[2], bw[3],
54062306a36Sopenharmony_ci					bw[4], bw[5], bw[6], bw[7]);
54162306a36Sopenharmony_ci		size -= temp;
54262306a36Sopenharmony_ci		next += temp;
54362306a36Sopenharmony_ci	}
54462306a36Sopenharmony_ci
54562306a36Sopenharmony_ci	/* Dump all the FS/LS tables */
54662306a36Sopenharmony_ci	list_for_each_entry(tt, &ehci->tt_list, tt_list) {
54762306a36Sopenharmony_ci		temp = scnprintf(next, size,
54862306a36Sopenharmony_ci				"\nTT %s port %d  FS/LS bandwidth allocation (us per frame)\n",
54962306a36Sopenharmony_ci				dev_name(&tt->usb_tt->hub->dev),
55062306a36Sopenharmony_ci				tt->tt_port + !!tt->usb_tt->multi);
55162306a36Sopenharmony_ci		size -= temp;
55262306a36Sopenharmony_ci		next += temp;
55362306a36Sopenharmony_ci
55462306a36Sopenharmony_ci		bf = tt->bandwidth;
55562306a36Sopenharmony_ci		temp = scnprintf(next, size,
55662306a36Sopenharmony_ci				"  %5u%5u%5u%5u%5u%5u%5u%5u\n",
55762306a36Sopenharmony_ci				bf[0], bf[1], bf[2], bf[3],
55862306a36Sopenharmony_ci					bf[4], bf[5], bf[6], bf[7]);
55962306a36Sopenharmony_ci		size -= temp;
56062306a36Sopenharmony_ci		next += temp;
56162306a36Sopenharmony_ci
56262306a36Sopenharmony_ci		temp = scnprintf(next, size,
56362306a36Sopenharmony_ci				"FS/LS budget (us per microframe)\n");
56462306a36Sopenharmony_ci		size -= temp;
56562306a36Sopenharmony_ci		next += temp;
56662306a36Sopenharmony_ci		compute_tt_budget(budget, tt);
56762306a36Sopenharmony_ci		for (i = 0; i < EHCI_BANDWIDTH_SIZE; i += 8) {
56862306a36Sopenharmony_ci			bw = &budget[i];
56962306a36Sopenharmony_ci			temp = scnprintf(next, size,
57062306a36Sopenharmony_ci					"%2u: %4u%4u%4u%4u%4u%4u%4u%4u\n",
57162306a36Sopenharmony_ci					i, bw[0], bw[1], bw[2], bw[3],
57262306a36Sopenharmony_ci						bw[4], bw[5], bw[6], bw[7]);
57362306a36Sopenharmony_ci			size -= temp;
57462306a36Sopenharmony_ci			next += temp;
57562306a36Sopenharmony_ci		}
57662306a36Sopenharmony_ci		list_for_each_entry(ps, &tt->ps_list, ps_list) {
57762306a36Sopenharmony_ci			temp = scnprintf(next, size,
57862306a36Sopenharmony_ci					"%s ep %02x:  %4u @ %2u.%u+%u mask %04x\n",
57962306a36Sopenharmony_ci					dev_name(&ps->udev->dev),
58062306a36Sopenharmony_ci					ps->ep->desc.bEndpointAddress,
58162306a36Sopenharmony_ci					ps->tt_usecs,
58262306a36Sopenharmony_ci					ps->bw_phase, ps->phase_uf,
58362306a36Sopenharmony_ci					ps->bw_period, ps->cs_mask);
58462306a36Sopenharmony_ci			size -= temp;
58562306a36Sopenharmony_ci			next += temp;
58662306a36Sopenharmony_ci		}
58762306a36Sopenharmony_ci	}
58862306a36Sopenharmony_ci	spin_unlock_irq(&ehci->lock);
58962306a36Sopenharmony_ci
59062306a36Sopenharmony_ci	return next - buf->output_buf;
59162306a36Sopenharmony_ci}
59262306a36Sopenharmony_ci
59362306a36Sopenharmony_cistatic unsigned output_buf_tds_dir(char *buf, struct ehci_hcd *ehci,
59462306a36Sopenharmony_ci		struct ehci_qh_hw *hw, struct ehci_qh *qh, unsigned size)
59562306a36Sopenharmony_ci{
59662306a36Sopenharmony_ci	u32			scratch = hc32_to_cpup(ehci, &hw->hw_info1);
59762306a36Sopenharmony_ci	struct ehci_qtd		*qtd;
59862306a36Sopenharmony_ci	char			*type = "";
59962306a36Sopenharmony_ci	unsigned		temp = 0;
60062306a36Sopenharmony_ci
60162306a36Sopenharmony_ci	/* count tds, get ep direction */
60262306a36Sopenharmony_ci	list_for_each_entry(qtd, &qh->qtd_list, qtd_list) {
60362306a36Sopenharmony_ci		temp++;
60462306a36Sopenharmony_ci		switch ((hc32_to_cpu(ehci, qtd->hw_token) >> 8)	& 0x03) {
60562306a36Sopenharmony_ci		case 0:
60662306a36Sopenharmony_ci			type = "out";
60762306a36Sopenharmony_ci			continue;
60862306a36Sopenharmony_ci		case 1:
60962306a36Sopenharmony_ci			type = "in";
61062306a36Sopenharmony_ci			continue;
61162306a36Sopenharmony_ci		}
61262306a36Sopenharmony_ci	}
61362306a36Sopenharmony_ci
61462306a36Sopenharmony_ci	return scnprintf(buf, size, " (%c%d ep%d%s [%d/%d] q%d p%d)",
61562306a36Sopenharmony_ci			speed_char(scratch), scratch & 0x007f,
61662306a36Sopenharmony_ci			(scratch >> 8) & 0x000f, type, qh->ps.usecs,
61762306a36Sopenharmony_ci			qh->ps.c_usecs, temp, 0x7ff & (scratch >> 16));
61862306a36Sopenharmony_ci}
61962306a36Sopenharmony_ci
62062306a36Sopenharmony_ci#define DBG_SCHED_LIMIT 64
62162306a36Sopenharmony_cistatic ssize_t fill_periodic_buffer(struct debug_buffer *buf)
62262306a36Sopenharmony_ci{
62362306a36Sopenharmony_ci	struct usb_hcd		*hcd;
62462306a36Sopenharmony_ci	struct ehci_hcd		*ehci;
62562306a36Sopenharmony_ci	unsigned long		flags;
62662306a36Sopenharmony_ci	union ehci_shadow	p, *seen;
62762306a36Sopenharmony_ci	unsigned		temp, size, seen_count;
62862306a36Sopenharmony_ci	char			*next;
62962306a36Sopenharmony_ci	unsigned		i;
63062306a36Sopenharmony_ci	__hc32			tag;
63162306a36Sopenharmony_ci
63262306a36Sopenharmony_ci	seen = kmalloc_array(DBG_SCHED_LIMIT, sizeof(*seen), GFP_ATOMIC);
63362306a36Sopenharmony_ci	if (!seen)
63462306a36Sopenharmony_ci		return 0;
63562306a36Sopenharmony_ci	seen_count = 0;
63662306a36Sopenharmony_ci
63762306a36Sopenharmony_ci	hcd = bus_to_hcd(buf->bus);
63862306a36Sopenharmony_ci	ehci = hcd_to_ehci(hcd);
63962306a36Sopenharmony_ci	next = buf->output_buf;
64062306a36Sopenharmony_ci	size = buf->alloc_size;
64162306a36Sopenharmony_ci
64262306a36Sopenharmony_ci	temp = scnprintf(next, size, "size = %d\n", ehci->periodic_size);
64362306a36Sopenharmony_ci	size -= temp;
64462306a36Sopenharmony_ci	next += temp;
64562306a36Sopenharmony_ci
64662306a36Sopenharmony_ci	/*
64762306a36Sopenharmony_ci	 * dump a snapshot of the periodic schedule.
64862306a36Sopenharmony_ci	 * iso changes, interrupt usually doesn't.
64962306a36Sopenharmony_ci	 */
65062306a36Sopenharmony_ci	spin_lock_irqsave(&ehci->lock, flags);
65162306a36Sopenharmony_ci	for (i = 0; i < ehci->periodic_size; i++) {
65262306a36Sopenharmony_ci		p = ehci->pshadow[i];
65362306a36Sopenharmony_ci		if (likely(!p.ptr))
65462306a36Sopenharmony_ci			continue;
65562306a36Sopenharmony_ci		tag = Q_NEXT_TYPE(ehci, ehci->periodic[i]);
65662306a36Sopenharmony_ci
65762306a36Sopenharmony_ci		temp = scnprintf(next, size, "%4d: ", i);
65862306a36Sopenharmony_ci		size -= temp;
65962306a36Sopenharmony_ci		next += temp;
66062306a36Sopenharmony_ci
66162306a36Sopenharmony_ci		do {
66262306a36Sopenharmony_ci			struct ehci_qh_hw *hw;
66362306a36Sopenharmony_ci
66462306a36Sopenharmony_ci			switch (hc32_to_cpu(ehci, tag)) {
66562306a36Sopenharmony_ci			case Q_TYPE_QH:
66662306a36Sopenharmony_ci				hw = p.qh->hw;
66762306a36Sopenharmony_ci				temp = scnprintf(next, size, " qh%d-%04x/%p",
66862306a36Sopenharmony_ci						p.qh->ps.period,
66962306a36Sopenharmony_ci						hc32_to_cpup(ehci,
67062306a36Sopenharmony_ci							&hw->hw_info2)
67162306a36Sopenharmony_ci							/* uframe masks */
67262306a36Sopenharmony_ci							& (QH_CMASK | QH_SMASK),
67362306a36Sopenharmony_ci						p.qh);
67462306a36Sopenharmony_ci				size -= temp;
67562306a36Sopenharmony_ci				next += temp;
67662306a36Sopenharmony_ci				/* don't repeat what follows this qh */
67762306a36Sopenharmony_ci				for (temp = 0; temp < seen_count; temp++) {
67862306a36Sopenharmony_ci					if (seen[temp].ptr != p.ptr)
67962306a36Sopenharmony_ci						continue;
68062306a36Sopenharmony_ci					if (p.qh->qh_next.ptr) {
68162306a36Sopenharmony_ci						temp = scnprintf(next, size,
68262306a36Sopenharmony_ci							" ...");
68362306a36Sopenharmony_ci						size -= temp;
68462306a36Sopenharmony_ci						next += temp;
68562306a36Sopenharmony_ci					}
68662306a36Sopenharmony_ci					break;
68762306a36Sopenharmony_ci				}
68862306a36Sopenharmony_ci				/* show more info the first time around */
68962306a36Sopenharmony_ci				if (temp == seen_count) {
69062306a36Sopenharmony_ci					temp = output_buf_tds_dir(next, ehci,
69162306a36Sopenharmony_ci						hw, p.qh, size);
69262306a36Sopenharmony_ci
69362306a36Sopenharmony_ci					if (seen_count < DBG_SCHED_LIMIT)
69462306a36Sopenharmony_ci						seen[seen_count++].qh = p.qh;
69562306a36Sopenharmony_ci				} else {
69662306a36Sopenharmony_ci					temp = 0;
69762306a36Sopenharmony_ci				}
69862306a36Sopenharmony_ci				tag = Q_NEXT_TYPE(ehci, hw->hw_next);
69962306a36Sopenharmony_ci				p = p.qh->qh_next;
70062306a36Sopenharmony_ci				break;
70162306a36Sopenharmony_ci			case Q_TYPE_FSTN:
70262306a36Sopenharmony_ci				temp = scnprintf(next, size,
70362306a36Sopenharmony_ci					" fstn-%8x/%p", p.fstn->hw_prev,
70462306a36Sopenharmony_ci					p.fstn);
70562306a36Sopenharmony_ci				tag = Q_NEXT_TYPE(ehci, p.fstn->hw_next);
70662306a36Sopenharmony_ci				p = p.fstn->fstn_next;
70762306a36Sopenharmony_ci				break;
70862306a36Sopenharmony_ci			case Q_TYPE_ITD:
70962306a36Sopenharmony_ci				temp = scnprintf(next, size,
71062306a36Sopenharmony_ci					" itd/%p", p.itd);
71162306a36Sopenharmony_ci				tag = Q_NEXT_TYPE(ehci, p.itd->hw_next);
71262306a36Sopenharmony_ci				p = p.itd->itd_next;
71362306a36Sopenharmony_ci				break;
71462306a36Sopenharmony_ci			case Q_TYPE_SITD:
71562306a36Sopenharmony_ci				temp = scnprintf(next, size,
71662306a36Sopenharmony_ci					" sitd%d-%04x/%p",
71762306a36Sopenharmony_ci					p.sitd->stream->ps.period,
71862306a36Sopenharmony_ci					hc32_to_cpup(ehci, &p.sitd->hw_uframe)
71962306a36Sopenharmony_ci						& 0x0000ffff,
72062306a36Sopenharmony_ci					p.sitd);
72162306a36Sopenharmony_ci				tag = Q_NEXT_TYPE(ehci, p.sitd->hw_next);
72262306a36Sopenharmony_ci				p = p.sitd->sitd_next;
72362306a36Sopenharmony_ci				break;
72462306a36Sopenharmony_ci			}
72562306a36Sopenharmony_ci			size -= temp;
72662306a36Sopenharmony_ci			next += temp;
72762306a36Sopenharmony_ci		} while (p.ptr);
72862306a36Sopenharmony_ci
72962306a36Sopenharmony_ci		temp = scnprintf(next, size, "\n");
73062306a36Sopenharmony_ci		size -= temp;
73162306a36Sopenharmony_ci		next += temp;
73262306a36Sopenharmony_ci	}
73362306a36Sopenharmony_ci	spin_unlock_irqrestore(&ehci->lock, flags);
73462306a36Sopenharmony_ci	kfree(seen);
73562306a36Sopenharmony_ci
73662306a36Sopenharmony_ci	return buf->alloc_size - size;
73762306a36Sopenharmony_ci}
73862306a36Sopenharmony_ci#undef DBG_SCHED_LIMIT
73962306a36Sopenharmony_ci
74062306a36Sopenharmony_cistatic const char *rh_state_string(struct ehci_hcd *ehci)
74162306a36Sopenharmony_ci{
74262306a36Sopenharmony_ci	switch (ehci->rh_state) {
74362306a36Sopenharmony_ci	case EHCI_RH_HALTED:
74462306a36Sopenharmony_ci		return "halted";
74562306a36Sopenharmony_ci	case EHCI_RH_SUSPENDED:
74662306a36Sopenharmony_ci		return "suspended";
74762306a36Sopenharmony_ci	case EHCI_RH_RUNNING:
74862306a36Sopenharmony_ci		return "running";
74962306a36Sopenharmony_ci	case EHCI_RH_STOPPING:
75062306a36Sopenharmony_ci		return "stopping";
75162306a36Sopenharmony_ci	}
75262306a36Sopenharmony_ci	return "?";
75362306a36Sopenharmony_ci}
75462306a36Sopenharmony_ci
75562306a36Sopenharmony_cistatic ssize_t fill_registers_buffer(struct debug_buffer *buf)
75662306a36Sopenharmony_ci{
75762306a36Sopenharmony_ci	struct usb_hcd		*hcd;
75862306a36Sopenharmony_ci	struct ehci_hcd		*ehci;
75962306a36Sopenharmony_ci	unsigned long		flags;
76062306a36Sopenharmony_ci	unsigned		temp, size, i;
76162306a36Sopenharmony_ci	char			*next, scratch[80];
76262306a36Sopenharmony_ci	static char		fmt[] = "%*s\n";
76362306a36Sopenharmony_ci	static char		label[] = "";
76462306a36Sopenharmony_ci
76562306a36Sopenharmony_ci	hcd = bus_to_hcd(buf->bus);
76662306a36Sopenharmony_ci	ehci = hcd_to_ehci(hcd);
76762306a36Sopenharmony_ci	next = buf->output_buf;
76862306a36Sopenharmony_ci	size = buf->alloc_size;
76962306a36Sopenharmony_ci
77062306a36Sopenharmony_ci	spin_lock_irqsave(&ehci->lock, flags);
77162306a36Sopenharmony_ci
77262306a36Sopenharmony_ci	if (!HCD_HW_ACCESSIBLE(hcd)) {
77362306a36Sopenharmony_ci		size = scnprintf(next, size,
77462306a36Sopenharmony_ci			"bus %s, device %s\n"
77562306a36Sopenharmony_ci			"%s\n"
77662306a36Sopenharmony_ci			"SUSPENDED (no register access)\n",
77762306a36Sopenharmony_ci			hcd->self.controller->bus->name,
77862306a36Sopenharmony_ci			dev_name(hcd->self.controller),
77962306a36Sopenharmony_ci			hcd->product_desc);
78062306a36Sopenharmony_ci		goto done;
78162306a36Sopenharmony_ci	}
78262306a36Sopenharmony_ci
78362306a36Sopenharmony_ci	/* Capability Registers */
78462306a36Sopenharmony_ci	i = HC_VERSION(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase));
78562306a36Sopenharmony_ci	temp = scnprintf(next, size,
78662306a36Sopenharmony_ci		"bus %s, device %s\n"
78762306a36Sopenharmony_ci		"%s\n"
78862306a36Sopenharmony_ci		"EHCI %x.%02x, rh state %s\n",
78962306a36Sopenharmony_ci		hcd->self.controller->bus->name,
79062306a36Sopenharmony_ci		dev_name(hcd->self.controller),
79162306a36Sopenharmony_ci		hcd->product_desc,
79262306a36Sopenharmony_ci		i >> 8, i & 0x0ff, rh_state_string(ehci));
79362306a36Sopenharmony_ci	size -= temp;
79462306a36Sopenharmony_ci	next += temp;
79562306a36Sopenharmony_ci
79662306a36Sopenharmony_ci#ifdef	CONFIG_USB_PCI
79762306a36Sopenharmony_ci	/* EHCI 0.96 and later may have "extended capabilities" */
79862306a36Sopenharmony_ci	if (dev_is_pci(hcd->self.controller)) {
79962306a36Sopenharmony_ci		struct pci_dev	*pdev;
80062306a36Sopenharmony_ci		u32		offset, cap, cap2;
80162306a36Sopenharmony_ci		unsigned	count = 256 / 4;
80262306a36Sopenharmony_ci
80362306a36Sopenharmony_ci		pdev = to_pci_dev(ehci_to_hcd(ehci)->self.controller);
80462306a36Sopenharmony_ci		offset = HCC_EXT_CAPS(ehci_readl(ehci,
80562306a36Sopenharmony_ci				&ehci->caps->hcc_params));
80662306a36Sopenharmony_ci		while (offset && count--) {
80762306a36Sopenharmony_ci			pci_read_config_dword(pdev, offset, &cap);
80862306a36Sopenharmony_ci			switch (cap & 0xff) {
80962306a36Sopenharmony_ci			case 1:
81062306a36Sopenharmony_ci				temp = scnprintf(next, size,
81162306a36Sopenharmony_ci					"ownership %08x%s%s\n", cap,
81262306a36Sopenharmony_ci					(cap & (1 << 24)) ? " linux" : "",
81362306a36Sopenharmony_ci					(cap & (1 << 16)) ? " firmware" : "");
81462306a36Sopenharmony_ci				size -= temp;
81562306a36Sopenharmony_ci				next += temp;
81662306a36Sopenharmony_ci
81762306a36Sopenharmony_ci				offset += 4;
81862306a36Sopenharmony_ci				pci_read_config_dword(pdev, offset, &cap2);
81962306a36Sopenharmony_ci				temp = scnprintf(next, size,
82062306a36Sopenharmony_ci					"SMI sts/enable 0x%08x\n", cap2);
82162306a36Sopenharmony_ci				size -= temp;
82262306a36Sopenharmony_ci				next += temp;
82362306a36Sopenharmony_ci				break;
82462306a36Sopenharmony_ci			case 0:		/* illegal reserved capability */
82562306a36Sopenharmony_ci				cap = 0;
82662306a36Sopenharmony_ci				fallthrough;
82762306a36Sopenharmony_ci			default:		/* unknown */
82862306a36Sopenharmony_ci				break;
82962306a36Sopenharmony_ci			}
83062306a36Sopenharmony_ci			offset = (cap >> 8) & 0xff;
83162306a36Sopenharmony_ci		}
83262306a36Sopenharmony_ci	}
83362306a36Sopenharmony_ci#endif
83462306a36Sopenharmony_ci
83562306a36Sopenharmony_ci	/* FIXME interpret both types of params */
83662306a36Sopenharmony_ci	i = ehci_readl(ehci, &ehci->caps->hcs_params);
83762306a36Sopenharmony_ci	temp = scnprintf(next, size, "structural params 0x%08x\n", i);
83862306a36Sopenharmony_ci	size -= temp;
83962306a36Sopenharmony_ci	next += temp;
84062306a36Sopenharmony_ci
84162306a36Sopenharmony_ci	i = ehci_readl(ehci, &ehci->caps->hcc_params);
84262306a36Sopenharmony_ci	temp = scnprintf(next, size, "capability params 0x%08x\n", i);
84362306a36Sopenharmony_ci	size -= temp;
84462306a36Sopenharmony_ci	next += temp;
84562306a36Sopenharmony_ci
84662306a36Sopenharmony_ci	/* Operational Registers */
84762306a36Sopenharmony_ci	temp = dbg_status_buf(scratch, sizeof(scratch), label,
84862306a36Sopenharmony_ci			ehci_readl(ehci, &ehci->regs->status));
84962306a36Sopenharmony_ci	temp = scnprintf(next, size, fmt, temp, scratch);
85062306a36Sopenharmony_ci	size -= temp;
85162306a36Sopenharmony_ci	next += temp;
85262306a36Sopenharmony_ci
85362306a36Sopenharmony_ci	temp = dbg_command_buf(scratch, sizeof(scratch), label,
85462306a36Sopenharmony_ci			ehci_readl(ehci, &ehci->regs->command));
85562306a36Sopenharmony_ci	temp = scnprintf(next, size, fmt, temp, scratch);
85662306a36Sopenharmony_ci	size -= temp;
85762306a36Sopenharmony_ci	next += temp;
85862306a36Sopenharmony_ci
85962306a36Sopenharmony_ci	temp = dbg_intr_buf(scratch, sizeof(scratch), label,
86062306a36Sopenharmony_ci			ehci_readl(ehci, &ehci->regs->intr_enable));
86162306a36Sopenharmony_ci	temp = scnprintf(next, size, fmt, temp, scratch);
86262306a36Sopenharmony_ci	size -= temp;
86362306a36Sopenharmony_ci	next += temp;
86462306a36Sopenharmony_ci
86562306a36Sopenharmony_ci	temp = scnprintf(next, size, "uframe %04x\n",
86662306a36Sopenharmony_ci			ehci_read_frame_index(ehci));
86762306a36Sopenharmony_ci	size -= temp;
86862306a36Sopenharmony_ci	next += temp;
86962306a36Sopenharmony_ci
87062306a36Sopenharmony_ci	for (i = 1; i <= HCS_N_PORTS(ehci->hcs_params); i++) {
87162306a36Sopenharmony_ci		temp = dbg_port_buf(scratch, sizeof(scratch), label, i,
87262306a36Sopenharmony_ci				ehci_readl(ehci,
87362306a36Sopenharmony_ci					&ehci->regs->port_status[i - 1]));
87462306a36Sopenharmony_ci		temp = scnprintf(next, size, fmt, temp, scratch);
87562306a36Sopenharmony_ci		size -= temp;
87662306a36Sopenharmony_ci		next += temp;
87762306a36Sopenharmony_ci		if (i == HCS_DEBUG_PORT(ehci->hcs_params) && ehci->debug) {
87862306a36Sopenharmony_ci			temp = scnprintf(next, size,
87962306a36Sopenharmony_ci					"    debug control %08x\n",
88062306a36Sopenharmony_ci					ehci_readl(ehci,
88162306a36Sopenharmony_ci						&ehci->debug->control));
88262306a36Sopenharmony_ci			size -= temp;
88362306a36Sopenharmony_ci			next += temp;
88462306a36Sopenharmony_ci		}
88562306a36Sopenharmony_ci	}
88662306a36Sopenharmony_ci
88762306a36Sopenharmony_ci	if (!list_empty(&ehci->async_unlink)) {
88862306a36Sopenharmony_ci		temp = scnprintf(next, size, "async unlink qh %p\n",
88962306a36Sopenharmony_ci				list_first_entry(&ehci->async_unlink,
89062306a36Sopenharmony_ci						struct ehci_qh, unlink_node));
89162306a36Sopenharmony_ci		size -= temp;
89262306a36Sopenharmony_ci		next += temp;
89362306a36Sopenharmony_ci	}
89462306a36Sopenharmony_ci
89562306a36Sopenharmony_ci#ifdef EHCI_STATS
89662306a36Sopenharmony_ci	temp = scnprintf(next, size,
89762306a36Sopenharmony_ci		"irq normal %ld err %ld iaa %ld (lost %ld)\n",
89862306a36Sopenharmony_ci		ehci->stats.normal, ehci->stats.error, ehci->stats.iaa,
89962306a36Sopenharmony_ci		ehci->stats.lost_iaa);
90062306a36Sopenharmony_ci	size -= temp;
90162306a36Sopenharmony_ci	next += temp;
90262306a36Sopenharmony_ci
90362306a36Sopenharmony_ci	temp = scnprintf(next, size, "complete %ld unlink %ld\n",
90462306a36Sopenharmony_ci		ehci->stats.complete, ehci->stats.unlink);
90562306a36Sopenharmony_ci	size -= temp;
90662306a36Sopenharmony_ci	next += temp;
90762306a36Sopenharmony_ci#endif
90862306a36Sopenharmony_ci
90962306a36Sopenharmony_cidone:
91062306a36Sopenharmony_ci	spin_unlock_irqrestore(&ehci->lock, flags);
91162306a36Sopenharmony_ci
91262306a36Sopenharmony_ci	return buf->alloc_size - size;
91362306a36Sopenharmony_ci}
91462306a36Sopenharmony_ci
91562306a36Sopenharmony_cistatic struct debug_buffer *alloc_buffer(struct usb_bus *bus,
91662306a36Sopenharmony_ci		ssize_t (*fill_func)(struct debug_buffer *))
91762306a36Sopenharmony_ci{
91862306a36Sopenharmony_ci	struct debug_buffer *buf;
91962306a36Sopenharmony_ci
92062306a36Sopenharmony_ci	buf = kzalloc(sizeof(*buf), GFP_KERNEL);
92162306a36Sopenharmony_ci
92262306a36Sopenharmony_ci	if (buf) {
92362306a36Sopenharmony_ci		buf->bus = bus;
92462306a36Sopenharmony_ci		buf->fill_func = fill_func;
92562306a36Sopenharmony_ci		mutex_init(&buf->mutex);
92662306a36Sopenharmony_ci		buf->alloc_size = PAGE_SIZE;
92762306a36Sopenharmony_ci	}
92862306a36Sopenharmony_ci
92962306a36Sopenharmony_ci	return buf;
93062306a36Sopenharmony_ci}
93162306a36Sopenharmony_ci
93262306a36Sopenharmony_cistatic int fill_buffer(struct debug_buffer *buf)
93362306a36Sopenharmony_ci{
93462306a36Sopenharmony_ci	int ret;
93562306a36Sopenharmony_ci
93662306a36Sopenharmony_ci	if (!buf->output_buf)
93762306a36Sopenharmony_ci		buf->output_buf = vmalloc(buf->alloc_size);
93862306a36Sopenharmony_ci
93962306a36Sopenharmony_ci	if (!buf->output_buf) {
94062306a36Sopenharmony_ci		ret = -ENOMEM;
94162306a36Sopenharmony_ci		goto out;
94262306a36Sopenharmony_ci	}
94362306a36Sopenharmony_ci
94462306a36Sopenharmony_ci	ret = buf->fill_func(buf);
94562306a36Sopenharmony_ci
94662306a36Sopenharmony_ci	if (ret >= 0) {
94762306a36Sopenharmony_ci		buf->count = ret;
94862306a36Sopenharmony_ci		ret = 0;
94962306a36Sopenharmony_ci	}
95062306a36Sopenharmony_ci
95162306a36Sopenharmony_ciout:
95262306a36Sopenharmony_ci	return ret;
95362306a36Sopenharmony_ci}
95462306a36Sopenharmony_ci
95562306a36Sopenharmony_cistatic ssize_t debug_output(struct file *file, char __user *user_buf,
95662306a36Sopenharmony_ci		size_t len, loff_t *offset)
95762306a36Sopenharmony_ci{
95862306a36Sopenharmony_ci	struct debug_buffer *buf = file->private_data;
95962306a36Sopenharmony_ci	int ret;
96062306a36Sopenharmony_ci
96162306a36Sopenharmony_ci	mutex_lock(&buf->mutex);
96262306a36Sopenharmony_ci	if (buf->count == 0) {
96362306a36Sopenharmony_ci		ret = fill_buffer(buf);
96462306a36Sopenharmony_ci		if (ret != 0) {
96562306a36Sopenharmony_ci			mutex_unlock(&buf->mutex);
96662306a36Sopenharmony_ci			goto out;
96762306a36Sopenharmony_ci		}
96862306a36Sopenharmony_ci	}
96962306a36Sopenharmony_ci	mutex_unlock(&buf->mutex);
97062306a36Sopenharmony_ci
97162306a36Sopenharmony_ci	ret = simple_read_from_buffer(user_buf, len, offset,
97262306a36Sopenharmony_ci				      buf->output_buf, buf->count);
97362306a36Sopenharmony_ci
97462306a36Sopenharmony_ciout:
97562306a36Sopenharmony_ci	return ret;
97662306a36Sopenharmony_ci}
97762306a36Sopenharmony_ci
97862306a36Sopenharmony_cistatic int debug_close(struct inode *inode, struct file *file)
97962306a36Sopenharmony_ci{
98062306a36Sopenharmony_ci	struct debug_buffer *buf = file->private_data;
98162306a36Sopenharmony_ci
98262306a36Sopenharmony_ci	if (buf) {
98362306a36Sopenharmony_ci		vfree(buf->output_buf);
98462306a36Sopenharmony_ci		kfree(buf);
98562306a36Sopenharmony_ci	}
98662306a36Sopenharmony_ci
98762306a36Sopenharmony_ci	return 0;
98862306a36Sopenharmony_ci}
98962306a36Sopenharmony_ci
99062306a36Sopenharmony_cistatic int debug_async_open(struct inode *inode, struct file *file)
99162306a36Sopenharmony_ci{
99262306a36Sopenharmony_ci	file->private_data = alloc_buffer(inode->i_private, fill_async_buffer);
99362306a36Sopenharmony_ci
99462306a36Sopenharmony_ci	return file->private_data ? 0 : -ENOMEM;
99562306a36Sopenharmony_ci}
99662306a36Sopenharmony_ci
99762306a36Sopenharmony_cistatic int debug_bandwidth_open(struct inode *inode, struct file *file)
99862306a36Sopenharmony_ci{
99962306a36Sopenharmony_ci	file->private_data = alloc_buffer(inode->i_private,
100062306a36Sopenharmony_ci			fill_bandwidth_buffer);
100162306a36Sopenharmony_ci
100262306a36Sopenharmony_ci	return file->private_data ? 0 : -ENOMEM;
100362306a36Sopenharmony_ci}
100462306a36Sopenharmony_ci
100562306a36Sopenharmony_cistatic int debug_periodic_open(struct inode *inode, struct file *file)
100662306a36Sopenharmony_ci{
100762306a36Sopenharmony_ci	struct debug_buffer *buf;
100862306a36Sopenharmony_ci
100962306a36Sopenharmony_ci	buf = alloc_buffer(inode->i_private, fill_periodic_buffer);
101062306a36Sopenharmony_ci	if (!buf)
101162306a36Sopenharmony_ci		return -ENOMEM;
101262306a36Sopenharmony_ci
101362306a36Sopenharmony_ci	buf->alloc_size = (sizeof(void *) == 4 ? 6 : 8) * PAGE_SIZE;
101462306a36Sopenharmony_ci	file->private_data = buf;
101562306a36Sopenharmony_ci	return 0;
101662306a36Sopenharmony_ci}
101762306a36Sopenharmony_ci
101862306a36Sopenharmony_cistatic int debug_registers_open(struct inode *inode, struct file *file)
101962306a36Sopenharmony_ci{
102062306a36Sopenharmony_ci	file->private_data = alloc_buffer(inode->i_private,
102162306a36Sopenharmony_ci					  fill_registers_buffer);
102262306a36Sopenharmony_ci
102362306a36Sopenharmony_ci	return file->private_data ? 0 : -ENOMEM;
102462306a36Sopenharmony_ci}
102562306a36Sopenharmony_ci
102662306a36Sopenharmony_cistatic inline void create_debug_files(struct ehci_hcd *ehci)
102762306a36Sopenharmony_ci{
102862306a36Sopenharmony_ci	struct usb_bus *bus = &ehci_to_hcd(ehci)->self;
102962306a36Sopenharmony_ci
103062306a36Sopenharmony_ci	ehci->debug_dir = debugfs_create_dir(bus->bus_name, ehci_debug_root);
103162306a36Sopenharmony_ci
103262306a36Sopenharmony_ci	debugfs_create_file("async", S_IRUGO, ehci->debug_dir, bus,
103362306a36Sopenharmony_ci			    &debug_async_fops);
103462306a36Sopenharmony_ci	debugfs_create_file("bandwidth", S_IRUGO, ehci->debug_dir, bus,
103562306a36Sopenharmony_ci			    &debug_bandwidth_fops);
103662306a36Sopenharmony_ci	debugfs_create_file("periodic", S_IRUGO, ehci->debug_dir, bus,
103762306a36Sopenharmony_ci			    &debug_periodic_fops);
103862306a36Sopenharmony_ci	debugfs_create_file("registers", S_IRUGO, ehci->debug_dir, bus,
103962306a36Sopenharmony_ci			    &debug_registers_fops);
104062306a36Sopenharmony_ci}
104162306a36Sopenharmony_ci
104262306a36Sopenharmony_cistatic inline void remove_debug_files(struct ehci_hcd *ehci)
104362306a36Sopenharmony_ci{
104462306a36Sopenharmony_ci	debugfs_remove_recursive(ehci->debug_dir);
104562306a36Sopenharmony_ci}
104662306a36Sopenharmony_ci
104762306a36Sopenharmony_ci#else /* CONFIG_DYNAMIC_DEBUG */
104862306a36Sopenharmony_ci
104962306a36Sopenharmony_cistatic inline void dbg_hcs_params(struct ehci_hcd *ehci, char *label) { }
105062306a36Sopenharmony_cistatic inline void dbg_hcc_params(struct ehci_hcd *ehci, char *label) { }
105162306a36Sopenharmony_ci
105262306a36Sopenharmony_cistatic inline void __maybe_unused dbg_qh(const char *label,
105362306a36Sopenharmony_ci		struct ehci_hcd *ehci, struct ehci_qh *qh) { }
105462306a36Sopenharmony_ci
105562306a36Sopenharmony_cistatic inline int __maybe_unused dbg_status_buf(const char *buf,
105662306a36Sopenharmony_ci		unsigned int len, const char *label, u32 status)
105762306a36Sopenharmony_ci{ return 0; }
105862306a36Sopenharmony_ci
105962306a36Sopenharmony_cistatic inline int __maybe_unused dbg_command_buf(const char *buf,
106062306a36Sopenharmony_ci		unsigned int len, const char *label, u32 command)
106162306a36Sopenharmony_ci{ return 0; }
106262306a36Sopenharmony_ci
106362306a36Sopenharmony_cistatic inline int __maybe_unused dbg_intr_buf(const char *buf,
106462306a36Sopenharmony_ci		unsigned int len, const char *label, u32 enable)
106562306a36Sopenharmony_ci{ return 0; }
106662306a36Sopenharmony_ci
106762306a36Sopenharmony_cistatic inline int __maybe_unused dbg_port_buf(char *buf,
106862306a36Sopenharmony_ci		unsigned int len, const char *label, int port, u32 status)
106962306a36Sopenharmony_ci{ return 0; }
107062306a36Sopenharmony_ci
107162306a36Sopenharmony_cistatic inline void dbg_status(struct ehci_hcd *ehci, const char *label,
107262306a36Sopenharmony_ci		u32 status) { }
107362306a36Sopenharmony_cistatic inline void dbg_cmd(struct ehci_hcd *ehci, const char *label,
107462306a36Sopenharmony_ci		u32 command) { }
107562306a36Sopenharmony_cistatic inline void dbg_port(struct ehci_hcd *ehci, const char *label,
107662306a36Sopenharmony_ci		int port, u32 status) { }
107762306a36Sopenharmony_ci
107862306a36Sopenharmony_cistatic inline void create_debug_files(struct ehci_hcd *bus) { }
107962306a36Sopenharmony_cistatic inline void remove_debug_files(struct ehci_hcd *bus) { }
108062306a36Sopenharmony_ci
108162306a36Sopenharmony_ci#endif /* CONFIG_DYNAMIC_DEBUG */
1082