aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci-dbg.c
diff options
context:
space:
mode:
authorSarah Sharp <sarah.a.sharp@linux.intel.com>2009-04-27 22:53:56 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-06-16 00:44:48 -0400
commit7f84eef0dafb1d318263d8b71c38700aaf2d530d (patch)
treed7de1ac3d91fb206a5cec2e85b0ad7f4a7b78b21 /drivers/usb/host/xhci-dbg.c
parenta74588f94655263b96dacbbf14aac0958d8b7409 (diff)
USB: xhci: No-op command queueing and irq handler.
xHCI host controllers can optionally implement a no-op test. This simple test ensures the OS has correctly setup all basic data structures and can correctly respond to interrupts from the host controller hardware. There are two rings exercised by the no-op test: the command ring, and the event ring. The host controller driver writes a no-op command TRB to the command ring, and rings the doorbell for the command ring (the first entry in the doorbell array). The hardware receives this event, places a command completion event on the event ring, and fires an interrupt. The host controller driver sees the interrupt, and checks the event ring for TRBs it can process, and sees the command completion event. (See the rules in xhci-ring.c for who "owns" a TRB. This is a simplified set of rules, and may not contain all the details that are in the xHCI 0.95 spec.) A timer fires every 60 seconds to debug the state of the hardware and command and event rings. This timer only runs if CONFIG_USB_XHCI_HCD_DEBUGGING is 'y'. Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
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}