source: mainline/uspace/drv/bus/usb/xhci/debug.c@ a35b458

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since a35b458 was a35b458, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 7 years ago

style: Remove trailing whitespace on _all_ lines, including empty ones, for particular file types.

Command used: tools/srepl '\s\+$' '' -- *.c *.h *.py *.sh *.s *.S *.ag

Currently, whitespace on empty lines is very inconsistent.
There are two basic choices: Either remove the whitespace, or keep empty lines
indented to the level of surrounding code. The former is AFAICT more common,
and also much easier to do automatically.

Alternatively, we could write script for automatic indentation, and use that
instead. However, if such a script exists, it's possible to use the indented
style locally, by having the editor apply relevant conversions on load/save,
without affecting remote repository. IMO, it makes more sense to adopt
the simpler rule.

  • Property mode set to 100644
File size: 12.0 KB
Line 
1/*
2 * Copyright (c) 2018 Ondrej Hlavaty, Jan Hrach
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup drvusbxhci
30 * @{
31 */
32/** @file
33 * Various functions to examine current state of the xHC.
34 */
35
36#include <inttypes.h>
37#include <byteorder.h>
38#include <usb/debug.h>
39
40#include "hw_struct/trb.h"
41#include "debug.h"
42#include "hc.h"
43
44#define PX "\t%-21s = "
45
46#define DUMP_REG_FIELD(ptr, title, size, ...) \
47 usb_log_debug(PX "%" PRIu##size, title, XHCI_REG_RD_FIELD(ptr, size, ##__VA_ARGS__))
48
49#define DUMP_REG_RANGE(ptr, title, size, ...) \
50 usb_log_debug(PX "%" PRIu##size, title, XHCI_REG_RD_RANGE(ptr, size, ##__VA_ARGS__))
51
52#define DUMP_REG_FLAG(ptr, title, size, ...) \
53 usb_log_debug(PX "%s", title, XHCI_REG_RD_FLAG(ptr, size, ##__VA_ARGS__) ? "true" : "false")
54
55#define DUMP_REG_INNER(set, title, field, size, type, ...) \
56 DUMP_REG_##type(&(set)->field, title, size, ##__VA_ARGS__)
57
58#define DUMP_REG(set, c) DUMP_REG_INNER(set, #c, c)
59
60/**
61 * Dumps all capability registers.
62 */
63void xhci_dump_cap_regs(const xhci_cap_regs_t *cap)
64{
65 usb_log_debug("Capabilities:");
66
67 DUMP_REG(cap, XHCI_CAP_LENGTH);
68 DUMP_REG(cap, XHCI_CAP_VERSION);
69 DUMP_REG(cap, XHCI_CAP_MAX_SLOTS);
70 DUMP_REG(cap, XHCI_CAP_MAX_INTRS);
71 DUMP_REG(cap, XHCI_CAP_MAX_PORTS);
72 DUMP_REG(cap, XHCI_CAP_IST);
73 DUMP_REG(cap, XHCI_CAP_ERST_MAX);
74 usb_log_debug(PX "%u", "Max Scratchpad bufs", xhci_get_max_spbuf(cap));
75 DUMP_REG(cap, XHCI_CAP_SPR);
76 DUMP_REG(cap, XHCI_CAP_U1EL);
77 DUMP_REG(cap, XHCI_CAP_U2EL);
78 DUMP_REG(cap, XHCI_CAP_AC64);
79 DUMP_REG(cap, XHCI_CAP_BNC);
80 DUMP_REG(cap, XHCI_CAP_CSZ);
81 DUMP_REG(cap, XHCI_CAP_PPC);
82 DUMP_REG(cap, XHCI_CAP_PIND);
83 DUMP_REG(cap, XHCI_CAP_C);
84 DUMP_REG(cap, XHCI_CAP_LTC);
85 DUMP_REG(cap, XHCI_CAP_NSS);
86 DUMP_REG(cap, XHCI_CAP_PAE);
87 DUMP_REG(cap, XHCI_CAP_SPC);
88 DUMP_REG(cap, XHCI_CAP_SEC);
89 DUMP_REG(cap, XHCI_CAP_CFC);
90 DUMP_REG(cap, XHCI_CAP_MAX_PSA_SIZE);
91 DUMP_REG(cap, XHCI_CAP_XECP);
92 DUMP_REG(cap, XHCI_CAP_DBOFF);
93 DUMP_REG(cap, XHCI_CAP_RTSOFF);
94 DUMP_REG(cap, XHCI_CAP_U3C);
95 DUMP_REG(cap, XHCI_CAP_CMC);
96 DUMP_REG(cap, XHCI_CAP_FSC);
97 DUMP_REG(cap, XHCI_CAP_CTC);
98 DUMP_REG(cap, XHCI_CAP_LEC);
99 DUMP_REG(cap, XHCI_CAP_CIC);
100}
101
102/**
103 * Dumps registers of one port.
104 */
105void xhci_dump_port(const xhci_port_regs_t *port)
106{
107 DUMP_REG(port, XHCI_PORT_CCS);
108 DUMP_REG(port, XHCI_PORT_PED);
109 DUMP_REG(port, XHCI_PORT_OCA);
110 DUMP_REG(port, XHCI_PORT_PR);
111 DUMP_REG(port, XHCI_PORT_PLS);
112 DUMP_REG(port, XHCI_PORT_PP);
113 DUMP_REG(port, XHCI_PORT_PS);
114 DUMP_REG(port, XHCI_PORT_PIC);
115 DUMP_REG(port, XHCI_PORT_LWS);
116 DUMP_REG(port, XHCI_PORT_CSC);
117 DUMP_REG(port, XHCI_PORT_PEC);
118 DUMP_REG(port, XHCI_PORT_WRC);
119 DUMP_REG(port, XHCI_PORT_OCC);
120 DUMP_REG(port, XHCI_PORT_PRC);
121 DUMP_REG(port, XHCI_PORT_PLC);
122 DUMP_REG(port, XHCI_PORT_CEC);
123 DUMP_REG(port, XHCI_PORT_CAS);
124 DUMP_REG(port, XHCI_PORT_WCE);
125 DUMP_REG(port, XHCI_PORT_WDE);
126 DUMP_REG(port, XHCI_PORT_WOE);
127 DUMP_REG(port, XHCI_PORT_DR);
128 DUMP_REG(port, XHCI_PORT_WPR);
129 DUMP_REG(port, XHCI_PORT_USB3_U1TO);
130 DUMP_REG(port, XHCI_PORT_USB3_U2TO);
131 DUMP_REG(port, XHCI_PORT_USB3_FLPMA);
132 DUMP_REG(port, XHCI_PORT_USB3_LEC);
133 DUMP_REG(port, XHCI_PORT_USB3_RLC);
134 DUMP_REG(port, XHCI_PORT_USB3_TLC);
135 DUMP_REG(port, XHCI_PORT_USB2_L1S);
136 DUMP_REG(port, XHCI_PORT_USB2_RWE);
137 DUMP_REG(port, XHCI_PORT_USB2_BESL);
138 DUMP_REG(port, XHCI_PORT_USB2_L1DS);
139 DUMP_REG(port, XHCI_PORT_USB2_HLE);
140 DUMP_REG(port, XHCI_PORT_USB2_TM);
141 DUMP_REG(port, XHCI_PORT_USB2_HIRDM);
142 DUMP_REG(port, XHCI_PORT_USB2_L1TO);
143 DUMP_REG(port, XHCI_PORT_USB2_BESLD);
144}
145
146/**
147 * Dumps all registers that define state of the HC.
148 */
149void xhci_dump_state(const xhci_hc_t *hc)
150{
151 usb_log_debug("Operational registers:");
152
153 DUMP_REG(hc->op_regs, XHCI_OP_RS);
154 DUMP_REG(hc->op_regs, XHCI_OP_HCRST);
155 DUMP_REG(hc->op_regs, XHCI_OP_INTE);
156 DUMP_REG(hc->op_regs, XHCI_OP_HSEE);
157 DUMP_REG(hc->op_regs, XHCI_OP_LHCRST);
158 DUMP_REG(hc->op_regs, XHCI_OP_CSS);
159 DUMP_REG(hc->op_regs, XHCI_OP_CRS);
160 DUMP_REG(hc->op_regs, XHCI_OP_EWE);
161 DUMP_REG(hc->op_regs, XHCI_OP_EU3S);
162 DUMP_REG(hc->op_regs, XHCI_OP_CME);
163 DUMP_REG(hc->op_regs, XHCI_OP_HCH);
164 DUMP_REG(hc->op_regs, XHCI_OP_HSE);
165 DUMP_REG(hc->op_regs, XHCI_OP_EINT);
166 DUMP_REG(hc->op_regs, XHCI_OP_PCD);
167 DUMP_REG(hc->op_regs, XHCI_OP_SSS);
168 DUMP_REG(hc->op_regs, XHCI_OP_RSS);
169 DUMP_REG(hc->op_regs, XHCI_OP_SRE);
170 DUMP_REG(hc->op_regs, XHCI_OP_CNR);
171 DUMP_REG(hc->op_regs, XHCI_OP_HCE);
172 DUMP_REG(hc->op_regs, XHCI_OP_PAGESIZE);
173 DUMP_REG(hc->op_regs, XHCI_OP_NOTIFICATION);
174 DUMP_REG(hc->op_regs, XHCI_OP_RCS);
175 DUMP_REG(hc->op_regs, XHCI_OP_CS);
176 DUMP_REG(hc->op_regs, XHCI_OP_CA);
177 DUMP_REG(hc->op_regs, XHCI_OP_CRR);
178 DUMP_REG(hc->op_regs, XHCI_OP_CRCR);
179 DUMP_REG(hc->op_regs, XHCI_OP_DCBAAP);
180 DUMP_REG(hc->rt_regs, XHCI_RT_MFINDEX);
181
182 usb_log_debug("Interrupter 0 state:");
183 DUMP_REG(&hc->rt_regs->ir[0], XHCI_INTR_IP);
184 DUMP_REG(&hc->rt_regs->ir[0], XHCI_INTR_IE);
185 DUMP_REG(&hc->rt_regs->ir[0], XHCI_INTR_IMI);
186 DUMP_REG(&hc->rt_regs->ir[0], XHCI_INTR_IMC);
187 DUMP_REG(&hc->rt_regs->ir[0], XHCI_INTR_ERSTSZ);
188 DUMP_REG(&hc->rt_regs->ir[0], XHCI_INTR_ERSTBA);
189 DUMP_REG(&hc->rt_regs->ir[0], XHCI_INTR_ERDP);
190}
191
192/**
193 * Dump registers of all ports.
194 */
195void xhci_dump_ports(const xhci_hc_t *hc)
196{
197 const size_t num_ports = XHCI_REG_RD(hc->cap_regs, XHCI_CAP_MAX_PORTS);
198 for (size_t i = 0; i < num_ports; i++) {
199 usb_log_debug("Port %zu state:", i);
200
201 xhci_dump_port(&hc->op_regs->portrs[i]);
202 }
203}
204
205static const char *trb_types [] = {
206 [0] = "<empty>",
207#define TRB(t) [XHCI_TRB_TYPE_##t] = #t
208 TRB(NORMAL),
209 TRB(SETUP_STAGE),
210 TRB(DATA_STAGE),
211 TRB(STATUS_STAGE),
212 TRB(ISOCH),
213 TRB(LINK),
214 TRB(EVENT_DATA),
215 TRB(NO_OP),
216 TRB(ENABLE_SLOT_CMD),
217 TRB(DISABLE_SLOT_CMD),
218 TRB(ADDRESS_DEVICE_CMD),
219 TRB(CONFIGURE_ENDPOINT_CMD),
220 TRB(EVALUATE_CONTEXT_CMD),
221 TRB(RESET_ENDPOINT_CMD),
222 TRB(STOP_ENDPOINT_CMD),
223 TRB(SET_TR_DEQUEUE_POINTER_CMD),
224 TRB(RESET_DEVICE_CMD),
225 TRB(FORCE_EVENT_CMD),
226 TRB(NEGOTIATE_BANDWIDTH_CMD),
227 TRB(SET_LATENCY_TOLERANCE_VALUE_CMD),
228 TRB(GET_PORT_BANDWIDTH_CMD),
229 TRB(FORCE_HEADER_CMD),
230 TRB(NO_OP_CMD),
231 TRB(TRANSFER_EVENT),
232 TRB(COMMAND_COMPLETION_EVENT),
233 TRB(PORT_STATUS_CHANGE_EVENT),
234 TRB(BANDWIDTH_REQUEST_EVENT),
235 TRB(DOORBELL_EVENT),
236 TRB(HOST_CONTROLLER_EVENT),
237 TRB(DEVICE_NOTIFICATION_EVENT),
238 TRB(MFINDEX_WRAP_EVENT),
239#undef TRB
240 [XHCI_TRB_TYPE_MAX] = NULL,
241};
242
243/**
244 * Stringify XHCI_TRB_TYPE_*.
245 */
246const char *xhci_trb_str_type(unsigned type)
247{
248 static char type_buf [20];
249
250 if (type < XHCI_TRB_TYPE_MAX && trb_types[type] != NULL)
251 return trb_types[type];
252
253 snprintf(type_buf, sizeof(type_buf), "<unknown (%u)>", type);
254 return type_buf;
255}
256
257/**
258 * Dump a TRB.
259 */
260void xhci_dump_trb(const xhci_trb_t *trb)
261{
262 usb_log_debug("TRB(%p): type %s, cycle %u, status 0x%#08" PRIx32 ", "
263 "parameter 0x%#016" PRIx64, trb, xhci_trb_str_type(TRB_TYPE(*trb)),
264 TRB_CYCLE(*trb), trb->status, trb->parameter);
265}
266
267static const char *ec_ids [] = {
268 [0] = "<empty>",
269#define EC(t) [XHCI_EC_##t] = #t
270 EC(USB_LEGACY),
271 EC(SUPPORTED_PROTOCOL),
272 EC(EXTENDED_POWER_MANAGEMENT),
273 EC(IOV),
274 EC(MSI),
275 EC(LOCALMEM),
276 EC(DEBUG),
277 EC(MSIX),
278#undef EC
279 [XHCI_EC_MAX] = NULL
280};
281
282/**
283 * Dump Extended Capability ID.
284 */
285const char *xhci_ec_str_id(unsigned id)
286{
287 static char buf [20];
288
289 if (id < XHCI_EC_MAX && ec_ids[id] != NULL)
290 return ec_ids[id];
291
292 snprintf(buf, sizeof(buf), "<unknown (%u)>", id);
293 return buf;
294}
295
296/**
297 * Dump Protocol Speed ID.
298 */
299static void xhci_dump_psi(const xhci_psi_t *psi)
300{
301 static const char speed_exp [] = " KMG";
302 static const char *psi_types [] = { "", " rsvd", " RX", " TX" };
303
304 usb_log_debug("Speed %u%s: %5u %cb/s, %s",
305 XHCI_REG_RD(psi, XHCI_PSI_PSIV),
306 psi_types[XHCI_REG_RD(psi, XHCI_PSI_PLT)],
307 XHCI_REG_RD(psi, XHCI_PSI_PSIM),
308 speed_exp[XHCI_REG_RD(psi, XHCI_PSI_PSIE)],
309 XHCI_REG_RD(psi, XHCI_PSI_PFD) ? "full-duplex" : "");
310}
311
312/**
313 * Dump given Extended Capability.
314 */
315void xhci_dump_extcap(const xhci_extcap_t *ec)
316{
317 xhci_sp_name_t name;
318 unsigned ports_from, ports_to;
319
320 unsigned id = XHCI_REG_RD(ec, XHCI_EC_CAP_ID);
321 usb_log_debug("Extended capability %s", xhci_ec_str_id(id));
322
323 switch (id) {
324 case XHCI_EC_SUPPORTED_PROTOCOL:
325 name.packed = host2uint32_t_le(XHCI_REG_RD(ec, XHCI_EC_SP_NAME));
326 ports_from = XHCI_REG_RD(ec, XHCI_EC_SP_CP_OFF);
327 ports_to = ports_from + XHCI_REG_RD(ec, XHCI_EC_SP_CP_COUNT) - 1;
328 unsigned psic = XHCI_REG_RD(ec, XHCI_EC_SP_PSIC);
329
330 usb_log_debug("\tProtocol %.4s%u.%u, ports %u-%u, "
331 "%u protocol speeds", name.str,
332 XHCI_REG_RD(ec, XHCI_EC_SP_MAJOR),
333 XHCI_REG_RD(ec, XHCI_EC_SP_MINOR),
334 ports_from, ports_to, psic);
335
336 for (unsigned i = 0; i < psic; i++)
337 xhci_dump_psi(xhci_extcap_psi(ec, i));
338 break;
339 }
340}
341
342void xhci_dump_slot_ctx(const struct xhci_slot_ctx *ctx)
343{
344#define SLOT_DUMP(name) usb_log_debug("\t" #name ":\t0x%x", XHCI_SLOT_##name(*ctx))
345 SLOT_DUMP(ROUTE_STRING);
346 SLOT_DUMP(SPEED);
347 SLOT_DUMP(MTT);
348 SLOT_DUMP(HUB);
349 SLOT_DUMP(CTX_ENTRIES);
350 SLOT_DUMP(MAX_EXIT_LATENCY);
351 SLOT_DUMP(ROOT_HUB_PORT);
352 SLOT_DUMP(NUM_PORTS);
353 SLOT_DUMP(TT_HUB_SLOT_ID);
354 SLOT_DUMP(TT_PORT_NUM);
355 SLOT_DUMP(TT_THINK_TIME);
356 SLOT_DUMP(INTERRUPTER);
357 SLOT_DUMP(DEVICE_ADDRESS);
358 SLOT_DUMP(STATE);
359#undef SLOT_DUMP
360}
361
362void xhci_dump_endpoint_ctx(const struct xhci_endpoint_ctx *ctx)
363{
364#define EP_DUMP_DW(name) usb_log_debug("\t" #name ":\t0x%x", XHCI_EP_##name(*ctx))
365#define EP_DUMP_QW(name) usb_log_debug("\t" #name ":\t0x%llx", XHCI_EP_##name(*ctx))
366 EP_DUMP_DW(STATE);
367 EP_DUMP_DW(MULT);
368 EP_DUMP_DW(MAX_P_STREAMS);
369 EP_DUMP_DW(LSA);
370 EP_DUMP_DW(INTERVAL);
371 EP_DUMP_DW(ERROR_COUNT);
372 EP_DUMP_DW(TYPE);
373 EP_DUMP_DW(HID);
374 EP_DUMP_DW(MAX_BURST_SIZE);
375 EP_DUMP_DW(MAX_PACKET_SIZE);
376 EP_DUMP_QW(DCS);
377 EP_DUMP_QW(TR_DPTR);
378 EP_DUMP_DW(MAX_ESIT_PAYLOAD_LO);
379 EP_DUMP_DW(MAX_ESIT_PAYLOAD_HI);
380#undef EP_DUMP_DW
381#undef EP_DUMP_QW
382}
383
384void xhci_dump_input_ctx(const xhci_hc_t * hc, const struct xhci_input_ctx *ictx)
385{
386 xhci_device_ctx_t *device_ctx = XHCI_GET_DEVICE_CTX(ictx, hc);
387 xhci_slot_ctx_t *slot_ctx = XHCI_GET_SLOT_CTX(device_ctx, hc);
388 xhci_input_ctrl_ctx_t *ctrl_ctx = XHCI_GET_CTRL_CTX(ictx, hc);
389
390 usb_log_debug("Input control context:");
391 usb_log_debug("\tDrop:\t0x%08x", xhci2host(32, ctrl_ctx->data[0]));
392 usb_log_debug("\tAdd:\t0x%08x", xhci2host(32, ctrl_ctx->data[1]));
393
394 usb_log_debug("\tConfig:\t0x%02x", XHCI_INPUT_CTRL_CTX_CONFIG_VALUE(*ctrl_ctx));
395 usb_log_debug("\tIface:\t0x%02x", XHCI_INPUT_CTRL_CTX_IFACE_NUMBER(*ctrl_ctx));
396 usb_log_debug("\tAlternate:\t0x%02x", XHCI_INPUT_CTRL_CTX_ALTER_SETTING(*ctrl_ctx));
397
398 usb_log_debug("Slot context:");
399 xhci_dump_slot_ctx(slot_ctx);
400
401 for (uint8_t dci = 1; dci <= XHCI_EP_COUNT; dci++)
402 if (XHCI_INPUT_CTRL_CTX_DROP(*ctrl_ctx, dci)
403 || XHCI_INPUT_CTRL_CTX_ADD(*ctrl_ctx, dci)) {
404 usb_log_debug("Endpoint context DCI %u:", dci);
405 xhci_ep_ctx_t *ep_ctx = XHCI_GET_EP_CTX(device_ctx, hc, dci);
406 xhci_dump_endpoint_ctx(ep_ctx);
407 }
408}
409
410/**
411 * @}
412 */
Note: See TracBrowser for help on using the repository browser.