diff options
Diffstat (limited to 'drivers/usb/host/xhci-dbg.c')
-rw-r--r-- | drivers/usb/host/xhci-dbg.c | 81 |
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 | ||
61 | void xhci_print_cap_regs(struct xhci_hcd *xhci) | 63 | void 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 | */ | ||
247 | void 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 | */ | ||
273 | void 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 | |||
284 | void 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 | |||
302 | void 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 | } | ||