diff options
author | Gerd Hoffmann <kraxel@redhat.com> | 2013-10-04 00:29:44 +0200 |
---|---|---|
committer | Sarah Sharp <sarah.a.sharp@linux.intel.com> | 2014-03-04 15:38:00 -0800 |
commit | 153413032c6ea624fccc6732aba27a57688a7f91 (patch) | |
tree | 2d6273e9835906c6a6385a2ed59adc2b42666d2e /drivers/usb/host/xhci.h | |
parent | e587b8b270d3706147c806d42cc4ac78232caac7 (diff) |
xhci: fix usb3 streams
xhci maintains a radix tree for each stream endpoint because it must
be able to map a trb address to the stream ring. Each ring segment
must be added to the ring for this to work. Currently xhci sticks
only the first segment of each stream ring into the radix tree.
Result is that things work initially, but as soon as the first segment
is full xhci can't map the trb address from the completion event to the
stream ring any more -> BOOM. You'll find this message in the logs:
ERROR Transfer event for disabled endpoint or incorrect stream ring
This patch adds a helper function to update the radix tree, and a
function to remove ring segments from the tree. Both functions loop
over the segment list and handles all segments instead of just the
first.
[Note: Sarah changed this patch to add radix_tree_maybe_preload() and
radix_tree_preload_end() calls around the radix tree insert, since we
can now insert entries in interrupt context. There are now two helper
functions to make the code cleaner, and those functions are moved to
make them static.]
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Diffstat (limited to 'drivers/usb/host/xhci.h')
-rw-r--r-- | drivers/usb/host/xhci.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 58ed9d088e6..a6aa98f19a1 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1341,6 +1341,7 @@ struct xhci_ring { unsigned int num_trbs_free_temp; enum xhci_ring_type type; bool last_td_was_short; + struct radix_tree_root *trb_address_map; }; struct xhci_erst_entry { |