^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (c) 2001-2002 by David Brownell
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) /* this file is part of ehci-hcd.c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #ifdef CONFIG_DYNAMIC_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * check the values in the HCSPARAMS register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * (host controller _Structural_ parameters)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * see EHCI spec, Table 2-4 for each value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) static void dbg_hcs_params(struct ehci_hcd *ehci, char *label)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) u32 params = ehci_readl(ehci, &ehci->caps->hcs_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) ehci_dbg(ehci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) "%s hcs_params 0x%x dbg=%d%s cc=%d pcc=%d%s%s ports=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) label, params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) HCS_DEBUG_PORT(params),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) HCS_INDICATOR(params) ? " ind" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) HCS_N_CC(params),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) HCS_N_PCC(params),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) HCS_PORTROUTED(params) ? "" : " ordered",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) HCS_PPC(params) ? "" : " !ppc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) HCS_N_PORTS(params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) /* Port routing, per EHCI 0.95 Spec, Section 2.2.5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) if (HCS_PORTROUTED(params)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) char buf[46], tmp[7], byte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) buf[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) for (i = 0; i < HCS_N_PORTS(params); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /* FIXME MIPS won't readb() ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) byte = readb(&ehci->caps->portroute[(i >> 1)]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) sprintf(tmp, "%d ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) (i & 0x1) ? byte & 0xf : (byte >> 4) & 0xf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) strcat(buf, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) ehci_dbg(ehci, "%s portroute %s\n", label, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * check the values in the HCCPARAMS register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * (host controller _Capability_ parameters)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * see EHCI Spec, Table 2-5 for each value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static void dbg_hcc_params(struct ehci_hcd *ehci, char *label)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) u32 params = ehci_readl(ehci, &ehci->caps->hcc_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (HCC_ISOC_CACHE(params)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) ehci_dbg(ehci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) "%s hcc_params %04x caching frame %s%s%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) label, params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) HCC_PGM_FRAMELISTLEN(params) ? "256/512/1024" : "1024",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) HCC_CANPARK(params) ? " park" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) HCC_64BIT_ADDR(params) ? " 64 bit addr" : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) ehci_dbg(ehci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) "%s hcc_params %04x thresh %d uframes %s%s%s%s%s%s%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) label,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) HCC_ISOC_THRES(params),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) HCC_PGM_FRAMELISTLEN(params) ? "256/512/1024" : "1024",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) HCC_CANPARK(params) ? " park" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) HCC_64BIT_ADDR(params) ? " 64 bit addr" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) HCC_LPM(params) ? " LPM" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) HCC_PER_PORT_CHANGE_EVENT(params) ? " ppce" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) HCC_HW_PREFETCH(params) ? " hw prefetch" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) HCC_32FRAME_PERIODIC_LIST(params) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) " 32 periodic list" : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) static void __maybe_unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) dbg_qtd(const char *label, struct ehci_hcd *ehci, struct ehci_qtd *qtd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) ehci_dbg(ehci, "%s td %p n%08x %08x t%08x p0=%08x\n", label, qtd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) hc32_to_cpup(ehci, &qtd->hw_next),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) hc32_to_cpup(ehci, &qtd->hw_alt_next),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) hc32_to_cpup(ehci, &qtd->hw_token),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) hc32_to_cpup(ehci, &qtd->hw_buf[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (qtd->hw_buf[1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) ehci_dbg(ehci, " p1=%08x p2=%08x p3=%08x p4=%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) hc32_to_cpup(ehci, &qtd->hw_buf[1]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) hc32_to_cpup(ehci, &qtd->hw_buf[2]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) hc32_to_cpup(ehci, &qtd->hw_buf[3]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) hc32_to_cpup(ehci, &qtd->hw_buf[4]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) static void __maybe_unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) dbg_qh(const char *label, struct ehci_hcd *ehci, struct ehci_qh *qh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) struct ehci_qh_hw *hw = qh->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) ehci_dbg(ehci, "%s qh %p n%08x info %x %x qtd %x\n", label,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) qh, hw->hw_next, hw->hw_info1, hw->hw_info2, hw->hw_current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) dbg_qtd("overlay", ehci, (struct ehci_qtd *) &hw->hw_qtd_next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static void __maybe_unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) dbg_itd(const char *label, struct ehci_hcd *ehci, struct ehci_itd *itd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) ehci_dbg(ehci, "%s [%d] itd %p, next %08x, urb %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) label, itd->frame, itd, hc32_to_cpu(ehci, itd->hw_next),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) itd->urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) ehci_dbg(ehci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) " trans: %08x %08x %08x %08x %08x %08x %08x %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) hc32_to_cpu(ehci, itd->hw_transaction[0]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) hc32_to_cpu(ehci, itd->hw_transaction[1]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) hc32_to_cpu(ehci, itd->hw_transaction[2]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) hc32_to_cpu(ehci, itd->hw_transaction[3]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) hc32_to_cpu(ehci, itd->hw_transaction[4]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) hc32_to_cpu(ehci, itd->hw_transaction[5]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) hc32_to_cpu(ehci, itd->hw_transaction[6]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) hc32_to_cpu(ehci, itd->hw_transaction[7]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) ehci_dbg(ehci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) " buf: %08x %08x %08x %08x %08x %08x %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) hc32_to_cpu(ehci, itd->hw_bufp[0]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) hc32_to_cpu(ehci, itd->hw_bufp[1]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) hc32_to_cpu(ehci, itd->hw_bufp[2]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) hc32_to_cpu(ehci, itd->hw_bufp[3]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) hc32_to_cpu(ehci, itd->hw_bufp[4]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) hc32_to_cpu(ehci, itd->hw_bufp[5]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) hc32_to_cpu(ehci, itd->hw_bufp[6]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) ehci_dbg(ehci, " index: %d %d %d %d %d %d %d %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) itd->index[0], itd->index[1], itd->index[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) itd->index[3], itd->index[4], itd->index[5],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) itd->index[6], itd->index[7]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static void __maybe_unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) dbg_sitd(const char *label, struct ehci_hcd *ehci, struct ehci_sitd *sitd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) ehci_dbg(ehci, "%s [%d] sitd %p, next %08x, urb %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) label, sitd->frame, sitd, hc32_to_cpu(ehci, sitd->hw_next),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) sitd->urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) ehci_dbg(ehci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) " addr %08x sched %04x result %08x buf %08x %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) hc32_to_cpu(ehci, sitd->hw_fullspeed_ep),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) hc32_to_cpu(ehci, sitd->hw_uframe),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) hc32_to_cpu(ehci, sitd->hw_results),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) hc32_to_cpu(ehci, sitd->hw_buf[0]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) hc32_to_cpu(ehci, sitd->hw_buf[1]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) static int __maybe_unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) dbg_status_buf(char *buf, unsigned len, const char *label, u32 status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) return scnprintf(buf, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) "%s%sstatus %04x%s%s%s%s%s%s%s%s%s%s%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) label, label[0] ? " " : "", status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) (status & STS_PPCE_MASK) ? " PPCE" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) (status & STS_ASS) ? " Async" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) (status & STS_PSS) ? " Periodic" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) (status & STS_RECL) ? " Recl" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) (status & STS_HALT) ? " Halt" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) (status & STS_IAA) ? " IAA" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) (status & STS_FATAL) ? " FATAL" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) (status & STS_FLR) ? " FLR" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) (status & STS_PCD) ? " PCD" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) (status & STS_ERR) ? " ERR" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) (status & STS_INT) ? " INT" : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) static int __maybe_unused
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) dbg_intr_buf(char *buf, unsigned len, const char *label, u32 enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) return scnprintf(buf, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) "%s%sintrenable %02x%s%s%s%s%s%s%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) label, label[0] ? " " : "", enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) (enable & STS_PPCE_MASK) ? " PPCE" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) (enable & STS_IAA) ? " IAA" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) (enable & STS_FATAL) ? " FATAL" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) (enable & STS_FLR) ? " FLR" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) (enable & STS_PCD) ? " PCD" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) (enable & STS_ERR) ? " ERR" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) (enable & STS_INT) ? " INT" : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) static const char *const fls_strings[] = { "1024", "512", "256", "??" };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) dbg_command_buf(char *buf, unsigned len, const char *label, u32 command)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) return scnprintf(buf, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) "%s%scommand %07x %s%s%s%s%s%s=%d ithresh=%d%s%s%s%s "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) "period=%s%s %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) label, label[0] ? " " : "", command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) (command & CMD_HIRD) ? " HIRD" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) (command & CMD_PPCEE) ? " PPCEE" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) (command & CMD_FSP) ? " FSP" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) (command & CMD_ASPE) ? " ASPE" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) (command & CMD_PSPE) ? " PSPE" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) (command & CMD_PARK) ? " park" : "(park)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) CMD_PARK_CNT(command),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) (command >> 16) & 0x3f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) (command & CMD_LRESET) ? " LReset" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) (command & CMD_IAAD) ? " IAAD" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) (command & CMD_ASE) ? " Async" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) (command & CMD_PSE) ? " Periodic" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) fls_strings[(command >> 2) & 0x3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) (command & CMD_RESET) ? " Reset" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) (command & CMD_RUN) ? "RUN" : "HALT");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) dbg_port_buf(char *buf, unsigned len, const char *label, int port, u32 status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) char *sig;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) /* signaling state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) switch (status & (3 << 10)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) case 0 << 10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) sig = "se0";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) case 1 << 10: /* low speed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) sig = "k";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) case 2 << 10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) sig = "j";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) sig = "?";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) return scnprintf(buf, len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) "%s%sport:%d status %06x %d %s%s%s%s%s%s "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) "sig=%s%s%s%s%s%s%s%s%s%s%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) label, label[0] ? " " : "", port, status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) status >> 25, /*device address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) (status & PORT_SSTS) >> 23 == PORTSC_SUSPEND_STS_ACK ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) " ACK" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) (status & PORT_SSTS) >> 23 == PORTSC_SUSPEND_STS_NYET ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) " NYET" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) (status & PORT_SSTS) >> 23 == PORTSC_SUSPEND_STS_STALL ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) " STALL" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) (status & PORT_SSTS) >> 23 == PORTSC_SUSPEND_STS_ERR ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) " ERR" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) (status & PORT_POWER) ? " POWER" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) (status & PORT_OWNER) ? " OWNER" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) sig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) (status & PORT_LPM) ? " LPM" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) (status & PORT_RESET) ? " RESET" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) (status & PORT_SUSPEND) ? " SUSPEND" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) (status & PORT_RESUME) ? " RESUME" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) (status & PORT_OCC) ? " OCC" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) (status & PORT_OC) ? " OC" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) (status & PORT_PEC) ? " PEC" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) (status & PORT_PE) ? " PE" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) (status & PORT_CSC) ? " CSC" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) (status & PORT_CONNECT) ? " CONNECT" : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) dbg_status(struct ehci_hcd *ehci, const char *label, u32 status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) char buf[80];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) dbg_status_buf(buf, sizeof(buf), label, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) ehci_dbg(ehci, "%s\n", buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) dbg_cmd(struct ehci_hcd *ehci, const char *label, u32 command)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) char buf[80];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) dbg_command_buf(buf, sizeof(buf), label, command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) ehci_dbg(ehci, "%s\n", buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) dbg_port(struct ehci_hcd *ehci, const char *label, int port, u32 status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) char buf[80];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) dbg_port_buf(buf, sizeof(buf), label, port, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) ehci_dbg(ehci, "%s\n", buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) /*-------------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) /* troubleshooting help: expose state in debugfs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) static int debug_async_open(struct inode *, struct file *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) static int debug_bandwidth_open(struct inode *, struct file *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) static int debug_periodic_open(struct inode *, struct file *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) static int debug_registers_open(struct inode *, struct file *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) static ssize_t debug_output(struct file*, char __user*, size_t, loff_t*);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) static int debug_close(struct inode *, struct file *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) static const struct file_operations debug_async_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) .open = debug_async_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) .read = debug_output,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) .release = debug_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) .llseek = default_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) static const struct file_operations debug_bandwidth_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) .open = debug_bandwidth_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) .read = debug_output,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) .release = debug_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) .llseek = default_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) static const struct file_operations debug_periodic_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) .open = debug_periodic_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) .read = debug_output,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) .release = debug_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) .llseek = default_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) static const struct file_operations debug_registers_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) .open = debug_registers_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) .read = debug_output,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) .release = debug_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) .llseek = default_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) static struct dentry *ehci_debug_root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) struct debug_buffer {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) ssize_t (*fill_func)(struct debug_buffer *); /* fill method */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) struct usb_bus *bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) struct mutex mutex; /* protect filling of buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) size_t count; /* number of characters filled into buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) char *output_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) size_t alloc_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) static inline char speed_char(u32 info1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) switch (info1 & (3 << 12)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) case QH_FULL_SPEED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) return 'f';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) case QH_LOW_SPEED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) return 'l';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) case QH_HIGH_SPEED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) return 'h';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) return '?';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) static inline char token_mark(struct ehci_hcd *ehci, __hc32 token)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) __u32 v = hc32_to_cpu(ehci, token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if (v & QTD_STS_ACTIVE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) return '*';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) if (v & QTD_STS_HALT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) return '-';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) if (!IS_SHORT_READ(v))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) return ' ';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) /* tries to advance through hw_alt_next */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) return '/';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) static void qh_lines(struct ehci_hcd *ehci, struct ehci_qh *qh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) char **nextp, unsigned *sizep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) u32 scratch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) u32 hw_curr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) struct list_head *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) struct ehci_qtd *td;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) unsigned temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) unsigned size = *sizep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) char *next = *nextp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) char mark;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) __le32 list_end = EHCI_LIST_END(ehci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) struct ehci_qh_hw *hw = qh->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if (hw->hw_qtd_next == list_end) /* NEC does this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) mark = '@';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) mark = token_mark(ehci, hw->hw_token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (mark == '/') { /* qh_alt_next controls qh advance? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) if ((hw->hw_alt_next & QTD_MASK(ehci))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) == ehci->async->hw->hw_alt_next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) mark = '#'; /* blocked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) else if (hw->hw_alt_next == list_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) mark = '.'; /* use hw_qtd_next */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) /* else alt_next points to some other qtd */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) scratch = hc32_to_cpup(ehci, &hw->hw_info1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) hw_curr = (mark == '*') ? hc32_to_cpup(ehci, &hw->hw_current) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) temp = scnprintf(next, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) "qh/%p dev%d %cs ep%d %08x %08x (%08x%c %s nak%d)"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) " [cur %08x next %08x buf[0] %08x]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) qh, scratch & 0x007f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) speed_char (scratch),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) (scratch >> 8) & 0x000f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) scratch, hc32_to_cpup(ehci, &hw->hw_info2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) hc32_to_cpup(ehci, &hw->hw_token), mark,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) (cpu_to_hc32(ehci, QTD_TOGGLE) & hw->hw_token)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) ? "data1" : "data0",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) (hc32_to_cpup(ehci, &hw->hw_alt_next) >> 1) & 0x0f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) hc32_to_cpup(ehci, &hw->hw_current),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) hc32_to_cpup(ehci, &hw->hw_qtd_next),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) hc32_to_cpup(ehci, &hw->hw_buf[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) size -= temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) next += temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) /* hc may be modifying the list as we read it ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) list_for_each(entry, &qh->qtd_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) char *type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) td = list_entry(entry, struct ehci_qtd, qtd_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) scratch = hc32_to_cpup(ehci, &td->hw_token);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) mark = ' ';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) if (hw_curr == td->qtd_dma) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) mark = '*';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) } else if (hw->hw_qtd_next == cpu_to_hc32(ehci, td->qtd_dma)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) mark = '+';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) } else if (QTD_LENGTH(scratch)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if (td->hw_alt_next == ehci->async->hw->hw_alt_next)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) mark = '#';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) else if (td->hw_alt_next != list_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) mark = '/';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) switch ((scratch >> 8) & 0x03) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) type = "out";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) type = "in";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) type = "setup";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) type = "?";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) temp = scnprintf(next, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) "\n\t%p%c%s len=%d %08x urb %p"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) " [td %08x buf[0] %08x]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) td, mark, type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) (scratch >> 16) & 0x7fff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) scratch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) td->urb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) (u32) td->qtd_dma,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) hc32_to_cpup(ehci, &td->hw_buf[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) size -= temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) next += temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) if (temp == size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) temp = scnprintf(next, size, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) size -= temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) next += temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) *sizep = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) *nextp = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) static ssize_t fill_async_buffer(struct debug_buffer *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) struct usb_hcd *hcd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) struct ehci_hcd *ehci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) unsigned temp, size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) char *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) struct ehci_qh *qh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) hcd = bus_to_hcd(buf->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) ehci = hcd_to_ehci(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) next = buf->output_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) size = buf->alloc_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) *next = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) * dumps a snapshot of the async schedule.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) * usually empty except for long-term bulk reads, or head.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) * one QH per line, and TDs we know about
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) spin_lock_irqsave(&ehci->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) for (qh = ehci->async->qh_next.qh; size > 0 && qh; qh = qh->qh_next.qh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) qh_lines(ehci, qh, &next, &size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) if (!list_empty(&ehci->async_unlink) && size > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) temp = scnprintf(next, size, "\nunlink =\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) size -= temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) next += temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) list_for_each_entry(qh, &ehci->async_unlink, unlink_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) if (size <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) qh_lines(ehci, qh, &next, &size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) spin_unlock_irqrestore(&ehci->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) return strlen(buf->output_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) static ssize_t fill_bandwidth_buffer(struct debug_buffer *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) struct ehci_hcd *ehci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) struct ehci_tt *tt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) struct ehci_per_sched *ps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) unsigned temp, size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) char *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) unsigned i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) u8 *bw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) u16 *bf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) u8 budget[EHCI_BANDWIDTH_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) ehci = hcd_to_ehci(bus_to_hcd(buf->bus));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) next = buf->output_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) size = buf->alloc_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) *next = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) spin_lock_irq(&ehci->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) /* Dump the HS bandwidth table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) temp = scnprintf(next, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) "HS bandwidth allocation (us per microframe)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) size -= temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) next += temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) for (i = 0; i < EHCI_BANDWIDTH_SIZE; i += 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) bw = &ehci->bandwidth[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) temp = scnprintf(next, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) "%2u: %4u%4u%4u%4u%4u%4u%4u%4u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) i, bw[0], bw[1], bw[2], bw[3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) bw[4], bw[5], bw[6], bw[7]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) size -= temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) next += temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) /* Dump all the FS/LS tables */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) list_for_each_entry(tt, &ehci->tt_list, tt_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) temp = scnprintf(next, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) "\nTT %s port %d FS/LS bandwidth allocation (us per frame)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) dev_name(&tt->usb_tt->hub->dev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) tt->tt_port + !!tt->usb_tt->multi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) size -= temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) next += temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) bf = tt->bandwidth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) temp = scnprintf(next, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) " %5u%5u%5u%5u%5u%5u%5u%5u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) bf[0], bf[1], bf[2], bf[3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) bf[4], bf[5], bf[6], bf[7]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) size -= temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) next += temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) temp = scnprintf(next, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) "FS/LS budget (us per microframe)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) size -= temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) next += temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) compute_tt_budget(budget, tt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) for (i = 0; i < EHCI_BANDWIDTH_SIZE; i += 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) bw = &budget[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) temp = scnprintf(next, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) "%2u: %4u%4u%4u%4u%4u%4u%4u%4u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) i, bw[0], bw[1], bw[2], bw[3],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) bw[4], bw[5], bw[6], bw[7]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) size -= temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) next += temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) list_for_each_entry(ps, &tt->ps_list, ps_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) temp = scnprintf(next, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) "%s ep %02x: %4u @ %2u.%u+%u mask %04x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) dev_name(&ps->udev->dev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) ps->ep->desc.bEndpointAddress,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) ps->tt_usecs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) ps->bw_phase, ps->phase_uf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) ps->bw_period, ps->cs_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) size -= temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) next += temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) spin_unlock_irq(&ehci->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) return next - buf->output_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) static unsigned output_buf_tds_dir(char *buf, struct ehci_hcd *ehci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) struct ehci_qh_hw *hw, struct ehci_qh *qh, unsigned size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) u32 scratch = hc32_to_cpup(ehci, &hw->hw_info1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) struct ehci_qtd *qtd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) char *type = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) unsigned temp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) /* count tds, get ep direction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) list_for_each_entry(qtd, &qh->qtd_list, qtd_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) temp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) switch ((hc32_to_cpu(ehci, qtd->hw_token) >> 8) & 0x03) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) type = "out";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) type = "in";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) return scnprintf(buf, size, " (%c%d ep%d%s [%d/%d] q%d p%d)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) speed_char(scratch), scratch & 0x007f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) (scratch >> 8) & 0x000f, type, qh->ps.usecs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) qh->ps.c_usecs, temp, 0x7ff & (scratch >> 16));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) #define DBG_SCHED_LIMIT 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) static ssize_t fill_periodic_buffer(struct debug_buffer *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) struct usb_hcd *hcd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) struct ehci_hcd *ehci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) union ehci_shadow p, *seen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) unsigned temp, size, seen_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) char *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) unsigned i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) __hc32 tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) seen = kmalloc_array(DBG_SCHED_LIMIT, sizeof(*seen), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) if (!seen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) seen_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) hcd = bus_to_hcd(buf->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) ehci = hcd_to_ehci(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) next = buf->output_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) size = buf->alloc_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) temp = scnprintf(next, size, "size = %d\n", ehci->periodic_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) size -= temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) next += temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) * dump a snapshot of the periodic schedule.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) * iso changes, interrupt usually doesn't.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) spin_lock_irqsave(&ehci->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) for (i = 0; i < ehci->periodic_size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) p = ehci->pshadow[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) if (likely(!p.ptr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) tag = Q_NEXT_TYPE(ehci, ehci->periodic[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) temp = scnprintf(next, size, "%4d: ", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) size -= temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) next += temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) struct ehci_qh_hw *hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) switch (hc32_to_cpu(ehci, tag)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) case Q_TYPE_QH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) hw = p.qh->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) temp = scnprintf(next, size, " qh%d-%04x/%p",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) p.qh->ps.period,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) hc32_to_cpup(ehci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) &hw->hw_info2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) /* uframe masks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) & (QH_CMASK | QH_SMASK),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) p.qh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) size -= temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) next += temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) /* don't repeat what follows this qh */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) for (temp = 0; temp < seen_count; temp++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) if (seen[temp].ptr != p.ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) if (p.qh->qh_next.ptr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) temp = scnprintf(next, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) " ...");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) size -= temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) next += temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) /* show more info the first time around */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) if (temp == seen_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) temp = output_buf_tds_dir(next, ehci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) hw, p.qh, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) if (seen_count < DBG_SCHED_LIMIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) seen[seen_count++].qh = p.qh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) temp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) tag = Q_NEXT_TYPE(ehci, hw->hw_next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) p = p.qh->qh_next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) case Q_TYPE_FSTN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) temp = scnprintf(next, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) " fstn-%8x/%p", p.fstn->hw_prev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) p.fstn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) tag = Q_NEXT_TYPE(ehci, p.fstn->hw_next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) p = p.fstn->fstn_next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) case Q_TYPE_ITD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) temp = scnprintf(next, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) " itd/%p", p.itd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) tag = Q_NEXT_TYPE(ehci, p.itd->hw_next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) p = p.itd->itd_next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) case Q_TYPE_SITD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) temp = scnprintf(next, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) " sitd%d-%04x/%p",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) p.sitd->stream->ps.period,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) hc32_to_cpup(ehci, &p.sitd->hw_uframe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) & 0x0000ffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) p.sitd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) tag = Q_NEXT_TYPE(ehci, p.sitd->hw_next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) p = p.sitd->sitd_next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) size -= temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) next += temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) } while (p.ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) temp = scnprintf(next, size, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) size -= temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) next += temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) spin_unlock_irqrestore(&ehci->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) kfree(seen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) return buf->alloc_size - size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) #undef DBG_SCHED_LIMIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) static const char *rh_state_string(struct ehci_hcd *ehci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) switch (ehci->rh_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) case EHCI_RH_HALTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) return "halted";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) case EHCI_RH_SUSPENDED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) return "suspended";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) case EHCI_RH_RUNNING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) return "running";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) case EHCI_RH_STOPPING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) return "stopping";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) return "?";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) static ssize_t fill_registers_buffer(struct debug_buffer *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) struct usb_hcd *hcd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) struct ehci_hcd *ehci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) unsigned temp, size, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) char *next, scratch[80];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) static char fmt[] = "%*s\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) static char label[] = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) hcd = bus_to_hcd(buf->bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) ehci = hcd_to_ehci(hcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) next = buf->output_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) size = buf->alloc_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) spin_lock_irqsave(&ehci->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) if (!HCD_HW_ACCESSIBLE(hcd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) size = scnprintf(next, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) "bus %s, device %s\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) "%s\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) "SUSPENDED (no register access)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) hcd->self.controller->bus->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) dev_name(hcd->self.controller),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) hcd->product_desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) /* Capability Registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) i = HC_VERSION(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) temp = scnprintf(next, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) "bus %s, device %s\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) "%s\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) "EHCI %x.%02x, rh state %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) hcd->self.controller->bus->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) dev_name(hcd->self.controller),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) hcd->product_desc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) i >> 8, i & 0x0ff, rh_state_string(ehci));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) size -= temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) next += temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) #ifdef CONFIG_USB_PCI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) /* EHCI 0.96 and later may have "extended capabilities" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) if (dev_is_pci(hcd->self.controller)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) struct pci_dev *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) u32 offset, cap, cap2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) unsigned count = 256 / 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) pdev = to_pci_dev(ehci_to_hcd(ehci)->self.controller);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) offset = HCC_EXT_CAPS(ehci_readl(ehci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) &ehci->caps->hcc_params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) while (offset && count--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) pci_read_config_dword(pdev, offset, &cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) switch (cap & 0xff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) temp = scnprintf(next, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) "ownership %08x%s%s\n", cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) (cap & (1 << 24)) ? " linux" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) (cap & (1 << 16)) ? " firmware" : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) size -= temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) next += temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) offset += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) pci_read_config_dword(pdev, offset, &cap2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) temp = scnprintf(next, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) "SMI sts/enable 0x%08x\n", cap2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) size -= temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) next += temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) case 0: /* illegal reserved capability */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) cap = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) default: /* unknown */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) offset = (cap >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) /* FIXME interpret both types of params */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) i = ehci_readl(ehci, &ehci->caps->hcs_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) temp = scnprintf(next, size, "structural params 0x%08x\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) size -= temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) next += temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) i = ehci_readl(ehci, &ehci->caps->hcc_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) temp = scnprintf(next, size, "capability params 0x%08x\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) size -= temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) next += temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) /* Operational Registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) temp = dbg_status_buf(scratch, sizeof(scratch), label,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) ehci_readl(ehci, &ehci->regs->status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) temp = scnprintf(next, size, fmt, temp, scratch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) size -= temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) next += temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) temp = dbg_command_buf(scratch, sizeof(scratch), label,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) ehci_readl(ehci, &ehci->regs->command));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) temp = scnprintf(next, size, fmt, temp, scratch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) size -= temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) next += temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) temp = dbg_intr_buf(scratch, sizeof(scratch), label,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) ehci_readl(ehci, &ehci->regs->intr_enable));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) temp = scnprintf(next, size, fmt, temp, scratch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) size -= temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) next += temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) temp = scnprintf(next, size, "uframe %04x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) ehci_read_frame_index(ehci));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) size -= temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) next += temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) for (i = 1; i <= HCS_N_PORTS(ehci->hcs_params); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) temp = dbg_port_buf(scratch, sizeof(scratch), label, i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) ehci_readl(ehci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) &ehci->regs->port_status[i - 1]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) temp = scnprintf(next, size, fmt, temp, scratch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) size -= temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) next += temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) if (i == HCS_DEBUG_PORT(ehci->hcs_params) && ehci->debug) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) temp = scnprintf(next, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) " debug control %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) ehci_readl(ehci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) &ehci->debug->control));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) size -= temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) next += temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) if (!list_empty(&ehci->async_unlink)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) temp = scnprintf(next, size, "async unlink qh %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) list_first_entry(&ehci->async_unlink,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) struct ehci_qh, unlink_node));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) size -= temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) next += temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) #ifdef EHCI_STATS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) temp = scnprintf(next, size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) "irq normal %ld err %ld iaa %ld (lost %ld)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) ehci->stats.normal, ehci->stats.error, ehci->stats.iaa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) ehci->stats.lost_iaa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) size -= temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) next += temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) temp = scnprintf(next, size, "complete %ld unlink %ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) ehci->stats.complete, ehci->stats.unlink);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) size -= temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) next += temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) spin_unlock_irqrestore(&ehci->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) return buf->alloc_size - size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) static struct debug_buffer *alloc_buffer(struct usb_bus *bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) ssize_t (*fill_func)(struct debug_buffer *))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) struct debug_buffer *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) buf = kzalloc(sizeof(*buf), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) if (buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) buf->bus = bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) buf->fill_func = fill_func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) mutex_init(&buf->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) buf->alloc_size = PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) return buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) static int fill_buffer(struct debug_buffer *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) if (!buf->output_buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) buf->output_buf = vmalloc(buf->alloc_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) if (!buf->output_buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) ret = buf->fill_func(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) if (ret >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) buf->count = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) static ssize_t debug_output(struct file *file, char __user *user_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) size_t len, loff_t *offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) struct debug_buffer *buf = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) mutex_lock(&buf->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) if (buf->count == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) ret = fill_buffer(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) mutex_unlock(&buf->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) mutex_unlock(&buf->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) ret = simple_read_from_buffer(user_buf, len, offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) buf->output_buf, buf->count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) static int debug_close(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) struct debug_buffer *buf = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) if (buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) vfree(buf->output_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) static int debug_async_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) file->private_data = alloc_buffer(inode->i_private, fill_async_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) return file->private_data ? 0 : -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) static int debug_bandwidth_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) file->private_data = alloc_buffer(inode->i_private,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) fill_bandwidth_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) return file->private_data ? 0 : -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) static int debug_periodic_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) struct debug_buffer *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) buf = alloc_buffer(inode->i_private, fill_periodic_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) buf->alloc_size = (sizeof(void *) == 4 ? 6 : 8) * PAGE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) file->private_data = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) static int debug_registers_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) file->private_data = alloc_buffer(inode->i_private,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) fill_registers_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) return file->private_data ? 0 : -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) static inline void create_debug_files(struct ehci_hcd *ehci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) struct usb_bus *bus = &ehci_to_hcd(ehci)->self;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) ehci->debug_dir = debugfs_create_dir(bus->bus_name, ehci_debug_root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) debugfs_create_file("async", S_IRUGO, ehci->debug_dir, bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) &debug_async_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) debugfs_create_file("bandwidth", S_IRUGO, ehci->debug_dir, bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) &debug_bandwidth_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) debugfs_create_file("periodic", S_IRUGO, ehci->debug_dir, bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) &debug_periodic_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) debugfs_create_file("registers", S_IRUGO, ehci->debug_dir, bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) &debug_registers_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) static inline void remove_debug_files(struct ehci_hcd *ehci)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) debugfs_remove_recursive(ehci->debug_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) #else /* CONFIG_DYNAMIC_DEBUG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) static inline void dbg_hcs_params(struct ehci_hcd *ehci, char *label) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) static inline void dbg_hcc_params(struct ehci_hcd *ehci, char *label) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) static inline void __maybe_unused dbg_qh(const char *label,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) struct ehci_hcd *ehci, struct ehci_qh *qh) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) static inline int __maybe_unused dbg_status_buf(const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) unsigned int len, const char *label, u32 status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) { return 0; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) static inline int __maybe_unused dbg_command_buf(const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) unsigned int len, const char *label, u32 command)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) { return 0; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) static inline int __maybe_unused dbg_intr_buf(const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) unsigned int len, const char *label, u32 enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) { return 0; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) static inline int __maybe_unused dbg_port_buf(char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) unsigned int len, const char *label, int port, u32 status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) { return 0; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) static inline void dbg_status(struct ehci_hcd *ehci, const char *label,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) u32 status) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) static inline void dbg_cmd(struct ehci_hcd *ehci, const char *label,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) u32 command) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) static inline void dbg_port(struct ehci_hcd *ehci, const char *label,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) int port, u32 status) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) static inline void create_debug_files(struct ehci_hcd *bus) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) static inline void remove_debug_files(struct ehci_hcd *bus) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) #endif /* CONFIG_DYNAMIC_DEBUG */