diff options
Diffstat (limited to 'drivers/usb/host/xhci-dbg.c')
-rw-r--r-- | drivers/usb/host/xhci-dbg.c | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/drivers/usb/host/xhci-dbg.c b/drivers/usb/host/xhci-dbg.c index 5724683cef16..6dbf7d856f80 100644 --- a/drivers/usb/host/xhci-dbg.c +++ b/drivers/usb/host/xhci-dbg.c | |||
@@ -230,6 +230,64 @@ void xhci_print_registers(struct xhci_hcd *xhci) | |||
230 | xhci_print_op_regs(xhci); | 230 | xhci_print_op_regs(xhci); |
231 | } | 231 | } |
232 | 232 | ||
233 | void xhci_print_trb_offsets(struct xhci_hcd *xhci, union xhci_trb *trb) | ||
234 | { | ||
235 | int i; | ||
236 | for (i = 0; i < 4; ++i) | ||
237 | xhci_dbg(xhci, "Offset 0x%x = 0x%x\n", | ||
238 | i*4, trb->generic.field[i]); | ||
239 | } | ||
240 | |||
241 | /** | ||
242 | * Debug a transfer request block (TRB). | ||
243 | */ | ||
244 | void xhci_debug_trb(struct xhci_hcd *xhci, union xhci_trb *trb) | ||
245 | { | ||
246 | u64 address; | ||
247 | u32 type = xhci_readl(xhci, &trb->link.control) & TRB_TYPE_BITMASK; | ||
248 | |||
249 | switch (type) { | ||
250 | case TRB_TYPE(TRB_LINK): | ||
251 | xhci_dbg(xhci, "Link TRB:\n"); | ||
252 | xhci_print_trb_offsets(xhci, trb); | ||
253 | |||
254 | address = trb->link.segment_ptr[0] + | ||
255 | (((u64) trb->link.segment_ptr[1]) << 32); | ||
256 | xhci_dbg(xhci, "Next ring segment DMA address = 0x%llx\n", address); | ||
257 | |||
258 | xhci_dbg(xhci, "Interrupter target = 0x%x\n", | ||
259 | GET_INTR_TARGET(trb->link.intr_target)); | ||
260 | xhci_dbg(xhci, "Cycle bit = %u\n", | ||
261 | (unsigned int) (trb->link.control & TRB_CYCLE)); | ||
262 | xhci_dbg(xhci, "Toggle cycle bit = %u\n", | ||
263 | (unsigned int) (trb->link.control & LINK_TOGGLE)); | ||
264 | xhci_dbg(xhci, "No Snoop bit = %u\n", | ||
265 | (unsigned int) (trb->link.control & TRB_NO_SNOOP)); | ||
266 | break; | ||
267 | case TRB_TYPE(TRB_TRANSFER): | ||
268 | address = trb->trans_event.buffer[0] + | ||
269 | (((u64) trb->trans_event.buffer[1]) << 32); | ||
270 | /* | ||
271 | * FIXME: look at flags to figure out if it's an address or if | ||
272 | * the data is directly in the buffer field. | ||
273 | */ | ||
274 | xhci_dbg(xhci, "DMA address or buffer contents= %llu\n", address); | ||
275 | break; | ||
276 | case TRB_TYPE(TRB_COMPLETION): | ||
277 | address = trb->event_cmd.cmd_trb[0] + | ||
278 | (((u64) trb->event_cmd.cmd_trb[1]) << 32); | ||
279 | xhci_dbg(xhci, "Command TRB pointer = %llu\n", address); | ||
280 | xhci_dbg(xhci, "Completion status = %u\n", | ||
281 | (unsigned int) GET_COMP_CODE(trb->event_cmd.status)); | ||
282 | xhci_dbg(xhci, "Flags = 0x%x\n", (unsigned int) trb->event_cmd.flags); | ||
283 | break; | ||
284 | default: | ||
285 | xhci_dbg(xhci, "Unknown TRB with TRB type ID %u\n", | ||
286 | (unsigned int) type>>10); | ||
287 | xhci_print_trb_offsets(xhci, trb); | ||
288 | break; | ||
289 | } | ||
290 | } | ||
233 | 291 | ||
234 | /** | 292 | /** |
235 | * Debug a segment with an xHCI ring. | 293 | * Debug a segment with an xHCI ring. |
@@ -261,6 +319,20 @@ void xhci_debug_segment(struct xhci_hcd *xhci, struct xhci_segment *seg) | |||
261 | } | 319 | } |
262 | } | 320 | } |
263 | 321 | ||
322 | void xhci_dbg_ring_ptrs(struct xhci_hcd *xhci, struct xhci_ring *ring) | ||
323 | { | ||
324 | xhci_dbg(xhci, "Ring deq = 0x%x (virt), 0x%x (dma)\n", | ||
325 | (unsigned int) ring->dequeue, | ||
326 | trb_virt_to_dma(ring->deq_seg, ring->dequeue)); | ||
327 | xhci_dbg(xhci, "Ring deq updated %u times\n", | ||
328 | ring->deq_updates); | ||
329 | xhci_dbg(xhci, "Ring enq = 0x%x (virt), 0x%x (dma)\n", | ||
330 | (unsigned int) ring->enqueue, | ||
331 | trb_virt_to_dma(ring->enq_seg, ring->enqueue)); | ||
332 | xhci_dbg(xhci, "Ring enq updated %u times\n", | ||
333 | ring->enq_updates); | ||
334 | } | ||
335 | |||
264 | /** | 336 | /** |
265 | * Debugging for an xHCI ring, which is a queue broken into multiple segments. | 337 | * Debugging for an xHCI ring, which is a queue broken into multiple segments. |
266 | * | 338 | * |
@@ -277,6 +349,10 @@ void xhci_debug_ring(struct xhci_hcd *xhci, struct xhci_ring *ring) | |||
277 | struct xhci_segment *first_seg = ring->first_seg; | 349 | struct xhci_segment *first_seg = ring->first_seg; |
278 | xhci_debug_segment(xhci, first_seg); | 350 | xhci_debug_segment(xhci, first_seg); |
279 | 351 | ||
352 | if (!ring->enq_updates && !ring->deq_updates) { | ||
353 | xhci_dbg(xhci, " Ring has not been updated\n"); | ||
354 | return; | ||
355 | } | ||
280 | for (seg = first_seg->next; seg != first_seg; seg = seg->next) | 356 | for (seg = first_seg->next; seg != first_seg; seg = seg->next) |
281 | xhci_debug_segment(xhci, seg); | 357 | xhci_debug_segment(xhci, seg); |
282 | } | 358 | } |