]> rtime.felk.cvut.cz Git - vajnamar/linux-xlnx.git/commitdiff
xhci: Use Cached ring during endpoint ring allocation
authorAnurag Kumar Vulisha <anurag.kumar.vulisha@xilinx.com>
Mon, 6 Mar 2017 07:15:57 +0000 (12:45 +0530)
committerMichal Simek <michal.simek@xilinx.com>
Mon, 6 Mar 2017 08:37:31 +0000 (09:37 +0100)
Currently during endpoint initialization, a new endpoint ring is alloacte
using xhci_ring_alloc(), if this function fails to allocate ring a cached
ring(if available) is assigned to endpoint ring.
This patch modifies the code that during endpoint initialization, if cached
ring is available it is assigned to the endpoint ring. If cached rings are
not available then xhci_ring_alloc() is called to allocate a new ring.
Doing so will avoid unncessary memory allocations if cached ring is already
available for use. This also fixes endpoint "Ring expansion failed" error
which occurs due to insufficient memory during ring expansion.

Signed-off-by: Anurag Kumar Vulisha <anuragku@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
drivers/usb/host/xhci-mem.c

index 6afe32381209d76cd0cf2f46d686a9f07a43f2c9..58b2dd6916b434c8cc012af8139e1c6a2fe93960 100644 (file)
@@ -1481,19 +1481,22 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
                mult = 0;
 
        /* Set up the endpoint ring */
-       virt_dev->eps[ep_index].new_ring =
-               xhci_ring_alloc(xhci, 2, 1, ring_type, max_packet, mem_flags);
-       if (!virt_dev->eps[ep_index].new_ring) {
+       if (virt_dev->num_rings_cached > 0) {
                /* Attempt to use the ring cache */
-               if (virt_dev->num_rings_cached == 0)
-                       return -ENOMEM;
                virt_dev->num_rings_cached--;
                virt_dev->eps[ep_index].new_ring =
                        virt_dev->ring_cache[virt_dev->num_rings_cached];
                virt_dev->ring_cache[virt_dev->num_rings_cached] = NULL;
                xhci_reinit_cached_ring(xhci, virt_dev->eps[ep_index].new_ring,
                                        1, ring_type);
+       } else {
+               virt_dev->eps[ep_index].new_ring =
+                       xhci_ring_alloc(xhci, 2, 1, ring_type, max_packet,
+                                       mem_flags);
+               if (!virt_dev->eps[ep_index].new_ring)
+                       return -ENOMEM;
        }
+
        virt_dev->eps[ep_index].skip = false;
        ep_ring = virt_dev->eps[ep_index].new_ring;