diff options
author | Sarah Sharp <sarah.a.sharp@linux.intel.com> | 2009-04-27 22:53:56 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-06-16 00:44:48 -0400 |
commit | 7f84eef0dafb1d318263d8b71c38700aaf2d530d (patch) | |
tree | d7de1ac3d91fb206a5cec2e85b0ad7f4a7b78b21 /drivers/usb/host/xhci-mem.c | |
parent | a74588f94655263b96dacbbf14aac0958d8b7409 (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-mem.c')
-rw-r--r-- | drivers/usb/host/xhci-mem.c | 11 |
1 files changed, 3 insertions, 8 deletions
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index be5a05b2021c..005d44641d81 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c | |||
@@ -172,7 +172,9 @@ static struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci, | |||
172 | } | 172 | } |
173 | /* The ring is empty, so the enqueue pointer == dequeue pointer */ | 173 | /* The ring is empty, so the enqueue pointer == dequeue pointer */ |
174 | ring->enqueue = ring->first_seg->trbs; | 174 | ring->enqueue = ring->first_seg->trbs; |
175 | ring->enq_seg = ring->first_seg; | ||
175 | ring->dequeue = ring->enqueue; | 176 | ring->dequeue = ring->enqueue; |
177 | ring->deq_seg = ring->first_seg; | ||
176 | /* The ring is initialized to 0. The producer must write 1 to the cycle | 178 | /* The ring is initialized to 0. The producer must write 1 to the cycle |
177 | * bit to handover ownership of the TRB, so PCS = 1. The consumer must | 179 | * bit to handover ownership of the TRB, so PCS = 1. The consumer must |
178 | * compare CCS to the cycle bit to check ownership, so CCS = 1. | 180 | * compare CCS to the cycle bit to check ownership, so CCS = 1. |
@@ -374,14 +376,7 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags) | |||
374 | xhci_writel(xhci, val, &xhci->ir_set->erst_base[0]); | 376 | xhci_writel(xhci, val, &xhci->ir_set->erst_base[0]); |
375 | 377 | ||
376 | /* Set the event ring dequeue address */ | 378 | /* Set the event ring dequeue address */ |
377 | xhci_dbg(xhci, "// Set ERST dequeue address for ir_set 0 = 0x%x%x\n", | 379 | set_hc_event_deq(xhci); |
378 | xhci->erst.entries[0].seg_addr[1], xhci->erst.entries[0].seg_addr[0]); | ||
379 | val = xhci_readl(xhci, &xhci->run_regs->ir_set[0].erst_dequeue[0]); | ||
380 | val &= ERST_PTR_MASK; | ||
381 | val |= (xhci->erst.entries[0].seg_addr[0] & ~ERST_PTR_MASK); | ||
382 | xhci_writel(xhci, val, &xhci->run_regs->ir_set[0].erst_dequeue[0]); | ||
383 | xhci_writel(xhci, xhci->erst.entries[0].seg_addr[1], | ||
384 | &xhci->run_regs->ir_set[0].erst_dequeue[1]); | ||
385 | xhci_dbg(xhci, "Wrote ERST address to ir_set 0.\n"); | 380 | xhci_dbg(xhci, "Wrote ERST address to ir_set 0.\n"); |
386 | xhci_print_ir_set(xhci, xhci->ir_set, 0); | 381 | xhci_print_ir_set(xhci, xhci->ir_set, 0); |
387 | 382 | ||