OSDN Git Service

usb: dwc3: gadget: use allocated/queued reqs for LST bit
authorFelipe Balbi <felipe.balbi@linux.intel.com>
Mon, 30 May 2016 10:38:32 +0000 (13:38 +0300)
committerFelipe Balbi <felipe.balbi@linux.intel.com>
Mon, 20 Jun 2016 09:32:50 +0000 (12:32 +0300)
Let's only set LST bit when we run out of space in
our TRB ring. For all other cases, we keep LST bit
unset which will prevent constant allocation and
deallocation of endpoint transfer resources.

Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
drivers/usb/dwc3/gadget.c

index a7c2548..eea4127 100644 (file)
@@ -897,7 +897,8 @@ static u32 dwc3_calc_trbs_left(struct dwc3_ep *dep)
 }
 
 static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep,
-               struct dwc3_request *req, unsigned int trbs_left)
+               struct dwc3_request *req, unsigned int trbs_left,
+               unsigned int more_coming)
 {
        struct usb_request *request = &req->request;
        struct scatterlist *sg = request->sg;
@@ -914,7 +915,8 @@ static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep,
                dma = sg_dma_address(s);
 
                if (sg_is_last(s)) {
-                       if (list_is_last(&req->list, &dep->pending_list))
+                       if (usb_endpoint_xfer_int(dep->endpoint.desc) ||
+                               !more_coming)
                                last = true;
 
                        chain = false;
@@ -935,7 +937,8 @@ static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep,
 }
 
 static void dwc3_prepare_one_trb_linear(struct dwc3_ep *dep,
-               struct dwc3_request *req, unsigned int trbs_left)
+               struct dwc3_request *req, unsigned int trbs_left,
+               unsigned int more_coming)
 {
        unsigned int    last = false;
        unsigned int    length;
@@ -948,7 +951,7 @@ static void dwc3_prepare_one_trb_linear(struct dwc3_ep *dep,
                last = true;
 
        /* Is this the last request? */
-       if (list_is_last(&req->list, &dep->pending_list))
+       if (usb_endpoint_xfer_int(dep->endpoint.desc) || !more_coming)
                last = true;
 
        dwc3_prepare_one_trb(dep, req, dma, length,
@@ -966,6 +969,7 @@ static void dwc3_prepare_one_trb_linear(struct dwc3_ep *dep,
 static void dwc3_prepare_trbs(struct dwc3_ep *dep)
 {
        struct dwc3_request     *req, *n;
+       unsigned int            more_coming;
        u32                     trbs_left;
 
        BUILD_BUG_ON_NOT_POWER_OF_2(DWC3_TRB_NUM);
@@ -974,11 +978,15 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep)
        if (!trbs_left)
                return;
 
+       more_coming = dep->allocated_requests - dep->queued_requests;
+
        list_for_each_entry_safe(req, n, &dep->pending_list, list) {
                if (req->request.num_mapped_sgs > 0)
-                       dwc3_prepare_one_trb_sg(dep, req, trbs_left--);
+                       dwc3_prepare_one_trb_sg(dep, req, trbs_left--,
+                                       more_coming);
                else
-                       dwc3_prepare_one_trb_linear(dep, req, trbs_left--);
+                       dwc3_prepare_one_trb_linear(dep, req, trbs_left--,
+                                       more_coming);
 
                if (!trbs_left)
                        return;