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