UPSTREAM: usb: dwc3: gadget: prepare TRBs on update transfers too

If we're updating transfers, we can also prepare as
many TRBs as we can fit in the ring. Let's start
doing that.

This patch 'solves' a limitation of how many TRBs we
can prepare when we're getting close the end of the
ring. Instead driver to prepare only up to end of
the ring, we check if we have space to wrap around
the ring properly.

Note that this only happens when our enqueue and
dequeue pointers are equal (which is the case for
bulk endpoints after an XferComplete event).

Change-Id: I3a3614061234f2408b39bd3bc235bb2bf5289dff
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Signed-off-by: Wu Liang feng <wulf@rock-chips.com>
(cherry picked from commit c4233573f6)
This commit is contained in:
Felipe Balbi
2016-05-12 14:08:34 +03:00
committed by Huang, Tao
parent 528a622810
commit ed60abb5ba

View File

@@ -880,16 +880,40 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
trace_dwc3_prepare_trb(dep, trb);
}
static u32 dwc3_calc_trbs_left(struct dwc3_ep *dep)
{
struct dwc3_trb *tmp;
/*
* If enqueue & dequeue are equal than it is either full or empty.
*
* One way to know for sure is if the TRB right before us has HWO bit
* set or not. If it has, then we're definitely full and can't fit any
* more transfers in our ring.
*/
if (dep->trb_enqueue == dep->trb_dequeue) {
/* If we're full, enqueue/dequeue are > 0 */
if (dep->trb_enqueue) {
tmp = &dep->trb_pool[dep->trb_enqueue - 1];
if (tmp->ctrl & DWC3_TRB_CTRL_HWO)
return 0;
}
return DWC3_TRB_NUM - 1;
}
return dep->trb_dequeue - dep->trb_enqueue;
}
/*
* dwc3_prepare_trbs - setup TRBs from requests
* @dep: endpoint for which requests are being prepared
* @starting: true if the endpoint is idle and no requests are queued.
*
* The function goes through the requests list and sets up TRBs for the
* transfers. The function returns once there are no more TRBs available or
* it runs out of requests.
*/
static void dwc3_prepare_trbs(struct dwc3_ep *dep, bool starting)
static void dwc3_prepare_trbs(struct dwc3_ep *dep)
{
struct dwc3_request *req, *n;
u32 trbs_left;
@@ -897,23 +921,7 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep, bool starting)
BUILD_BUG_ON_NOT_POWER_OF_2(DWC3_TRB_NUM);
trbs_left = dep->trb_dequeue - dep->trb_enqueue;
/*
* If enqueue & dequeue are equal than it is either full or empty. If we
* are starting to process requests then we are empty. Otherwise we are
* full and don't do anything
*/
if (!trbs_left) {
if (!starting)
return;
trbs_left = DWC3_TRB_NUM;
}
/* The last TRB is a link TRB, not used for xfer */
if (trbs_left <= 1)
return;
trbs_left = dwc3_calc_trbs_left(dep);
list_for_each_entry_safe(req, n, &dep->pending_list, list) {
unsigned length;
@@ -996,12 +1004,12 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param,
*/
if (start_new) {
if (list_empty(&dep->started_list))
dwc3_prepare_trbs(dep, start_new);
dwc3_prepare_trbs(dep);
/* req points to the first request which will be sent */
req = next_request(&dep->started_list);
} else {
dwc3_prepare_trbs(dep, start_new);
dwc3_prepare_trbs(dep);
/*
* req points to the first request where HWO changed from 0 to 1