diff options
author | Mathias Nyman <mathias.nyman@linux.intel.com> | 2016-06-21 09:58:02 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2016-06-26 20:43:39 +0200 |
commit | f9c589e142d04b8a19eb382162f804d17102b5ed (patch) | |
tree | 89b9be15971379d0e6d8655138322239c02f8df9 /drivers/usb/host/xhci.c | |
parent | xhci: align the last trb before link if it is easily splittable. (diff) | |
download | linux-f9c589e142d04b8a19eb382162f804d17102b5ed.tar.xz linux-f9c589e142d04b8a19eb382162f804d17102b5ed.zip |
xhci: TD-fragment, align the unsplittable case with a bounce buffer
If the last trb before a link is not packet size aligned, and is not
splittable then use a bounce buffer for that chunk of max packet size
unalignable data.
Allocate a max packet size bounce buffer for every segment of a bulk
endpoint ring at the same time as allocating the ring.
If we need to align the data before the link trb in that segment then
copy the data to the segment bounce buffer, dma map it, and enqueue it.
Once the td finishes, or is cancelled, unmap it.
For in transfers we need to first map the bounce buffer, then queue it,
after it finishes, copy the bounce buffer to the original sg list, and
finally unmap it
Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/host/xhci.c')
-rw-r--r-- | drivers/usb/host/xhci.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index f2f9518c53ab..9da98321d8e6 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -3139,6 +3139,7 @@ int xhci_alloc_streams(struct usb_hcd *hcd, struct usb_device *udev, struct xhci_input_control_ctx *ctrl_ctx; unsigned int ep_index; unsigned int num_stream_ctxs; + unsigned int max_packet; unsigned long flags; u32 changed_ep_bitmask = 0; @@ -3212,9 +3213,11 @@ int xhci_alloc_streams(struct usb_hcd *hcd, struct usb_device *udev, for (i = 0; i < num_eps; i++) { ep_index = xhci_get_endpoint_index(&eps[i]->desc); + max_packet = GET_MAX_PACKET(usb_endpoint_maxp(&eps[i]->desc)); vdev->eps[ep_index].stream_info = xhci_alloc_stream_info(xhci, num_stream_ctxs, - num_streams, mem_flags); + num_streams, + max_packet, mem_flags); if (!vdev->eps[ep_index].stream_info) goto cleanup; /* Set maxPstreams in endpoint context and update deq ptr to |