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.c76
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
233void 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 */
244void 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
322void 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}