aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci-dbg.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/xhci-dbg.c')
-rw-r--r--drivers/usb/host/xhci-dbg.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/drivers/usb/host/xhci-dbg.c b/drivers/usb/host/xhci-dbg.c
index a7798b460492..5724683cef16 100644
--- a/drivers/usb/host/xhci-dbg.c
+++ b/drivers/usb/host/xhci-dbg.c
@@ -56,6 +56,8 @@ void xhci_dbg_regs(struct xhci_hcd *xhci)
56 temp = xhci_readl(xhci, &xhci->cap_regs->db_off); 56 temp = xhci_readl(xhci, &xhci->cap_regs->db_off);
57 xhci_dbg(xhci, "// @%x = 0x%x DBOFF\n", 57 xhci_dbg(xhci, "// @%x = 0x%x DBOFF\n",
58 (unsigned int) &xhci->cap_regs->db_off, temp); 58 (unsigned int) &xhci->cap_regs->db_off, temp);
59 xhci_dbg(xhci, "// Doorbell array at 0x%x:\n",
60 (unsigned int) xhci->dba);
59} 61}
60 62
61void xhci_print_cap_regs(struct xhci_hcd *xhci) 63void xhci_print_cap_regs(struct xhci_hcd *xhci)
@@ -227,3 +229,82 @@ void xhci_print_registers(struct xhci_hcd *xhci)
227 xhci_print_cap_regs(xhci); 229 xhci_print_cap_regs(xhci);
228 xhci_print_op_regs(xhci); 230 xhci_print_op_regs(xhci);
229} 231}
232
233
234/**
235 * Debug a segment with an xHCI ring.
236 *
237 * @return The Link TRB of the segment, or NULL if there is no Link TRB
238 * (which is a bug, since all segments must have a Link TRB).
239 *
240 * Prints out all TRBs in the segment, even those after the Link TRB.
241 *
242 * XXX: should we print out TRBs that the HC owns? As long as we don't
243 * write, that should be fine... We shouldn't expect that the memory pointed to
244 * by the TRB is valid at all. Do we care about ones the HC owns? Probably,
245 * for HC debugging.
246 */
247void xhci_debug_segment(struct xhci_hcd *xhci, struct xhci_segment *seg)
248{
249 int i;
250 u32 addr = (u32) seg->dma;
251 union xhci_trb *trb = seg->trbs;
252
253 for (i = 0; i < TRBS_PER_SEGMENT; ++i) {
254 trb = &seg->trbs[i];
255 xhci_dbg(xhci, "@%08x %08x %08x %08x %08x\n", addr,
256 (unsigned int) trb->link.segment_ptr[0],
257 (unsigned int) trb->link.segment_ptr[1],
258 (unsigned int) trb->link.intr_target,
259 (unsigned int) trb->link.control);
260 addr += sizeof(*trb);
261 }
262}
263
264/**
265 * Debugging for an xHCI ring, which is a queue broken into multiple segments.
266 *
267 * Print out each segment in the ring. Check that the DMA address in
268 * each link segment actually matches the segment's stored DMA address.
269 * Check that the link end bit is only set at the end of the ring.
270 * Check that the dequeue and enqueue pointers point to real data in this ring
271 * (not some other ring).
272 */
273void xhci_debug_ring(struct xhci_hcd *xhci, struct xhci_ring *ring)
274{
275 /* FIXME: Throw an error if any segment doesn't have a Link TRB */
276 struct xhci_segment *seg;
277 struct xhci_segment *first_seg = ring->first_seg;
278 xhci_debug_segment(xhci, first_seg);
279
280 for (seg = first_seg->next; seg != first_seg; seg = seg->next)
281 xhci_debug_segment(xhci, seg);
282}
283
284void xhci_dbg_erst(struct xhci_hcd *xhci, struct xhci_erst *erst)
285{
286 u32 addr = (u32) erst->erst_dma_addr;
287 int i;
288 struct xhci_erst_entry *entry;
289
290 for (i = 0; i < erst->num_entries; ++i) {
291 entry = &erst->entries[i];
292 xhci_dbg(xhci, "@%08x %08x %08x %08x %08x\n",
293 (unsigned int) addr,
294 (unsigned int) entry->seg_addr[0],
295 (unsigned int) entry->seg_addr[1],
296 (unsigned int) entry->seg_size,
297 (unsigned int) entry->rsvd);
298 addr += sizeof(*entry);
299 }
300}
301
302void xhci_dbg_cmd_ptrs(struct xhci_hcd *xhci)
303{
304 u32 val;
305
306 val = xhci_readl(xhci, &xhci->op_regs->cmd_ring[0]);
307 xhci_dbg(xhci, "// xHC command ring deq ptr low bits + flags = 0x%x\n", val);
308 val = xhci_readl(xhci, &xhci->op_regs->cmd_ring[1]);
309 xhci_dbg(xhci, "// xHC command ring deq ptr high bits = 0x%x\n", val);
310}