diff options
Diffstat (limited to 'drivers/usb/host/xhci-dbg.c')
-rw-r--r-- | drivers/usb/host/xhci-dbg.c | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/drivers/usb/host/xhci-dbg.c b/drivers/usb/host/xhci-dbg.c new file mode 100644 index 000000000000..a7798b460492 --- /dev/null +++ b/drivers/usb/host/xhci-dbg.c | |||
@@ -0,0 +1,229 @@ | |||
1 | /* | ||
2 | * xHCI host controller driver | ||
3 | * | ||
4 | * Copyright (C) 2008 Intel Corp. | ||
5 | * | ||
6 | * Author: Sarah Sharp | ||
7 | * Some code borrowed from the Linux EHCI driver. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but | ||
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | ||
15 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
16 | * for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software Foundation, | ||
20 | * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | */ | ||
22 | |||
23 | #include "xhci.h" | ||
24 | |||
25 | #define XHCI_INIT_VALUE 0x0 | ||
26 | |||
27 | /* Add verbose debugging later, just print everything for now */ | ||
28 | |||
29 | void xhci_dbg_regs(struct xhci_hcd *xhci) | ||
30 | { | ||
31 | u32 temp; | ||
32 | |||
33 | xhci_dbg(xhci, "// xHCI capability registers at 0x%x:\n", | ||
34 | (unsigned int) xhci->cap_regs); | ||
35 | temp = xhci_readl(xhci, &xhci->cap_regs->hc_capbase); | ||
36 | xhci_dbg(xhci, "// @%x = 0x%x (CAPLENGTH AND HCIVERSION)\n", | ||
37 | (unsigned int) &xhci->cap_regs->hc_capbase, | ||
38 | (unsigned int) temp); | ||
39 | xhci_dbg(xhci, "// CAPLENGTH: 0x%x\n", | ||
40 | (unsigned int) HC_LENGTH(temp)); | ||
41 | #if 0 | ||
42 | xhci_dbg(xhci, "// HCIVERSION: 0x%x\n", | ||
43 | (unsigned int) HC_VERSION(temp)); | ||
44 | #endif | ||
45 | |||
46 | xhci_dbg(xhci, "// xHCI operational registers at 0x%x:\n", | ||
47 | (unsigned int) xhci->op_regs); | ||
48 | |||
49 | temp = xhci_readl(xhci, &xhci->cap_regs->run_regs_off); | ||
50 | xhci_dbg(xhci, "// @%x = 0x%x RTSOFF\n", | ||
51 | (unsigned int) &xhci->cap_regs->run_regs_off, | ||
52 | (unsigned int) temp & RTSOFF_MASK); | ||
53 | xhci_dbg(xhci, "// xHCI runtime registers at 0x%x:\n", | ||
54 | (unsigned int) xhci->run_regs); | ||
55 | |||
56 | temp = xhci_readl(xhci, &xhci->cap_regs->db_off); | ||
57 | xhci_dbg(xhci, "// @%x = 0x%x DBOFF\n", | ||
58 | (unsigned int) &xhci->cap_regs->db_off, temp); | ||
59 | } | ||
60 | |||
61 | void xhci_print_cap_regs(struct xhci_hcd *xhci) | ||
62 | { | ||
63 | u32 temp; | ||
64 | |||
65 | xhci_dbg(xhci, "xHCI capability registers at 0x%x:\n", | ||
66 | (unsigned int) xhci->cap_regs); | ||
67 | |||
68 | temp = xhci_readl(xhci, &xhci->cap_regs->hc_capbase); | ||
69 | xhci_dbg(xhci, "CAPLENGTH AND HCIVERSION 0x%x:\n", | ||
70 | (unsigned int) temp); | ||
71 | xhci_dbg(xhci, "CAPLENGTH: 0x%x\n", | ||
72 | (unsigned int) HC_LENGTH(temp)); | ||
73 | xhci_dbg(xhci, "HCIVERSION: 0x%x\n", | ||
74 | (unsigned int) HC_VERSION(temp)); | ||
75 | |||
76 | temp = xhci_readl(xhci, &xhci->cap_regs->hcs_params1); | ||
77 | xhci_dbg(xhci, "HCSPARAMS 1: 0x%x\n", | ||
78 | (unsigned int) temp); | ||
79 | xhci_dbg(xhci, " Max device slots: %u\n", | ||
80 | (unsigned int) HCS_MAX_SLOTS(temp)); | ||
81 | xhci_dbg(xhci, " Max interrupters: %u\n", | ||
82 | (unsigned int) HCS_MAX_INTRS(temp)); | ||
83 | xhci_dbg(xhci, " Max ports: %u\n", | ||
84 | (unsigned int) HCS_MAX_PORTS(temp)); | ||
85 | |||
86 | temp = xhci_readl(xhci, &xhci->cap_regs->hcs_params2); | ||
87 | xhci_dbg(xhci, "HCSPARAMS 2: 0x%x\n", | ||
88 | (unsigned int) temp); | ||
89 | xhci_dbg(xhci, " Isoc scheduling threshold: %u\n", | ||
90 | (unsigned int) HCS_IST(temp)); | ||
91 | xhci_dbg(xhci, " Maximum allowed segments in event ring: %u\n", | ||
92 | (unsigned int) HCS_ERST_MAX(temp)); | ||
93 | |||
94 | temp = xhci_readl(xhci, &xhci->cap_regs->hcs_params3); | ||
95 | xhci_dbg(xhci, "HCSPARAMS 3 0x%x:\n", | ||
96 | (unsigned int) temp); | ||
97 | xhci_dbg(xhci, " Worst case U1 device exit latency: %u\n", | ||
98 | (unsigned int) HCS_U1_LATENCY(temp)); | ||
99 | xhci_dbg(xhci, " Worst case U2 device exit latency: %u\n", | ||
100 | (unsigned int) HCS_U2_LATENCY(temp)); | ||
101 | |||
102 | temp = xhci_readl(xhci, &xhci->cap_regs->hcc_params); | ||
103 | xhci_dbg(xhci, "HCC PARAMS 0x%x:\n", (unsigned int) temp); | ||
104 | xhci_dbg(xhci, " HC generates %s bit addresses\n", | ||
105 | HCC_64BIT_ADDR(temp) ? "64" : "32"); | ||
106 | /* FIXME */ | ||
107 | xhci_dbg(xhci, " FIXME: more HCCPARAMS debugging\n"); | ||
108 | |||
109 | temp = xhci_readl(xhci, &xhci->cap_regs->run_regs_off); | ||
110 | xhci_dbg(xhci, "RTSOFF 0x%x:\n", temp & RTSOFF_MASK); | ||
111 | } | ||
112 | |||
113 | void xhci_print_command_reg(struct xhci_hcd *xhci) | ||
114 | { | ||
115 | u32 temp; | ||
116 | |||
117 | temp = xhci_readl(xhci, &xhci->op_regs->command); | ||
118 | xhci_dbg(xhci, "USBCMD 0x%x:\n", temp); | ||
119 | xhci_dbg(xhci, " HC is %s\n", | ||
120 | (temp & CMD_RUN) ? "running" : "being stopped"); | ||
121 | xhci_dbg(xhci, " HC has %sfinished hard reset\n", | ||
122 | (temp & CMD_RESET) ? "not " : ""); | ||
123 | xhci_dbg(xhci, " Event Interrupts %s\n", | ||
124 | (temp & CMD_EIE) ? "enabled " : "disabled"); | ||
125 | xhci_dbg(xhci, " Host System Error Interrupts %s\n", | ||
126 | (temp & CMD_EIE) ? "enabled " : "disabled"); | ||
127 | xhci_dbg(xhci, " HC has %sfinished light reset\n", | ||
128 | (temp & CMD_LRESET) ? "not " : ""); | ||
129 | } | ||
130 | |||
131 | void xhci_print_status(struct xhci_hcd *xhci) | ||
132 | { | ||
133 | u32 temp; | ||
134 | |||
135 | temp = xhci_readl(xhci, &xhci->op_regs->status); | ||
136 | xhci_dbg(xhci, "USBSTS 0x%x:\n", temp); | ||
137 | xhci_dbg(xhci, " Event ring is %sempty\n", | ||
138 | (temp & STS_EINT) ? "not " : ""); | ||
139 | xhci_dbg(xhci, " %sHost System Error\n", | ||
140 | (temp & STS_FATAL) ? "WARNING: " : "No "); | ||
141 | xhci_dbg(xhci, " HC is %s\n", | ||
142 | (temp & STS_HALT) ? "halted" : "running"); | ||
143 | } | ||
144 | |||
145 | void xhci_print_op_regs(struct xhci_hcd *xhci) | ||
146 | { | ||
147 | xhci_dbg(xhci, "xHCI operational registers at 0x%x:\n", | ||
148 | (unsigned int) xhci->op_regs); | ||
149 | xhci_print_command_reg(xhci); | ||
150 | xhci_print_status(xhci); | ||
151 | } | ||
152 | |||
153 | void xhci_print_ir_set(struct xhci_hcd *xhci, struct intr_reg *ir_set, int set_num) | ||
154 | { | ||
155 | void *addr; | ||
156 | u32 temp; | ||
157 | |||
158 | addr = &ir_set->irq_pending; | ||
159 | temp = xhci_readl(xhci, addr); | ||
160 | if (temp == XHCI_INIT_VALUE) | ||
161 | return; | ||
162 | |||
163 | xhci_dbg(xhci, " 0x%x: ir_set[%i]\n", (unsigned int) ir_set, set_num); | ||
164 | |||
165 | xhci_dbg(xhci, " 0x%x: ir_set.pending = 0x%x\n", | ||
166 | (unsigned int) addr, (unsigned int) temp); | ||
167 | |||
168 | addr = &ir_set->irq_control; | ||
169 | temp = xhci_readl(xhci, addr); | ||
170 | xhci_dbg(xhci, " 0x%x: ir_set.control = 0x%x\n", | ||
171 | (unsigned int) addr, (unsigned int) temp); | ||
172 | |||
173 | addr = &ir_set->erst_size; | ||
174 | temp = xhci_readl(xhci, addr); | ||
175 | xhci_dbg(xhci, " 0x%x: ir_set.erst_size = 0x%x\n", | ||
176 | (unsigned int) addr, (unsigned int) temp); | ||
177 | |||
178 | addr = &ir_set->rsvd; | ||
179 | temp = xhci_readl(xhci, addr); | ||
180 | if (temp != XHCI_INIT_VALUE) | ||
181 | xhci_dbg(xhci, " WARN: 0x%x: ir_set.rsvd = 0x%x\n", | ||
182 | (unsigned int) addr, (unsigned int) temp); | ||
183 | |||
184 | addr = &ir_set->erst_base[0]; | ||
185 | temp = xhci_readl(xhci, addr); | ||
186 | xhci_dbg(xhci, " 0x%x: ir_set.erst_base[0] = 0x%x\n", | ||
187 | (unsigned int) addr, (unsigned int) temp); | ||
188 | |||
189 | addr = &ir_set->erst_base[1]; | ||
190 | temp = xhci_readl(xhci, addr); | ||
191 | xhci_dbg(xhci, " 0x%x: ir_set.erst_base[1] = 0x%x\n", | ||
192 | (unsigned int) addr, (unsigned int) temp); | ||
193 | |||
194 | addr = &ir_set->erst_dequeue[0]; | ||
195 | temp = xhci_readl(xhci, addr); | ||
196 | xhci_dbg(xhci, " 0x%x: ir_set.erst_dequeue[0] = 0x%x\n", | ||
197 | (unsigned int) addr, (unsigned int) temp); | ||
198 | |||
199 | addr = &ir_set->erst_dequeue[1]; | ||
200 | temp = xhci_readl(xhci, addr); | ||
201 | xhci_dbg(xhci, " 0x%x: ir_set.erst_dequeue[1] = 0x%x\n", | ||
202 | (unsigned int) addr, (unsigned int) temp); | ||
203 | } | ||
204 | |||
205 | void xhci_print_run_regs(struct xhci_hcd *xhci) | ||
206 | { | ||
207 | u32 temp; | ||
208 | int i; | ||
209 | |||
210 | xhci_dbg(xhci, "xHCI runtime registers at 0x%x:\n", | ||
211 | (unsigned int) xhci->run_regs); | ||
212 | temp = xhci_readl(xhci, &xhci->run_regs->microframe_index); | ||
213 | xhci_dbg(xhci, " 0x%x: Microframe index = 0x%x\n", | ||
214 | (unsigned int) &xhci->run_regs->microframe_index, | ||
215 | (unsigned int) temp); | ||
216 | for (i = 0; i < 7; ++i) { | ||
217 | temp = xhci_readl(xhci, &xhci->run_regs->rsvd[i]); | ||
218 | if (temp != XHCI_INIT_VALUE) | ||
219 | xhci_dbg(xhci, " WARN: 0x%x: Rsvd[%i] = 0x%x\n", | ||
220 | (unsigned int) &xhci->run_regs->rsvd[i], | ||
221 | i, (unsigned int) temp); | ||
222 | } | ||
223 | } | ||
224 | |||
225 | void xhci_print_registers(struct xhci_hcd *xhci) | ||
226 | { | ||
227 | xhci_print_cap_regs(xhci); | ||
228 | xhci_print_op_regs(xhci); | ||
229 | } | ||