Some functions might want to have very, very long request queues. We
can't make any assumptions about how many requests we *are* able to
map, so instead of mapping requests early, let's map them late. This
way, functions can queue as many requests as they'd like but we won't
take DMA resources until they are needed.

Also, we can now stop processing requests when we run out of DMA
resources but still keep requests in the queue for late processing.

Signed-off-by: Felipe Balbi <[email protected]>
---

Tested with g_mass_storage using 1024 requests. Note that we have
space for 255 TRBs in our ring. TRB #256 is our link TRB back to
the head of the ring.

 drivers/usb/dwc3/gadget.c | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 7113a9f53ca9..750364eb11e1 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -1099,6 +1099,17 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep)
        }
 
        list_for_each_entry_safe(req, n, &dep->pending_list, list) {
+               struct dwc3     *dwc = dep->dwc;
+               int             ret;
+
+               ret = usb_gadget_map_request_by_dev(dwc->sysdev, &req->request,
+                                                   dep->direction);
+               if (ret)
+                       return;
+
+               req->sg                 = req->request.sg;
+               req->num_pending_sgs    = req->request.num_mapped_sgs;
+
                if (req->num_pending_sgs > 0)
                        dwc3_prepare_one_trb_sg(dep, req);
                else
@@ -1205,7 +1216,7 @@ static void dwc3_gadget_start_isoc(struct dwc3 *dwc,
 static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request 
*req)
 {
        struct dwc3             *dwc = dep->dwc;
-       int                     ret;
+       int                     ret = 0;
 
        if (!dep->endpoint.desc) {
                dev_err(dwc->dev, "%s: can't queue to disabled endpoint\n",
@@ -1229,14 +1240,6 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, 
struct dwc3_request *req)
 
        trace_dwc3_ep_queue(req);
 
-       ret = usb_gadget_map_request_by_dev(dwc->sysdev, &req->request,
-                                           dep->direction);
-       if (ret)
-               return ret;
-
-       req->sg                 = req->request.sg;
-       req->num_pending_sgs    = req->request.num_mapped_sgs;
-
        list_add_tail(&req->list, &dep->pending_list);
 
        /*
-- 
2.11.0.295.gd7dffce1ce

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to