|
@@ -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;
|