usb: dwc3: gadget: Revise setting IOC when no TRB left
To keep the setting of interrupt-on-completion (IOC) when out of TRBs consistent and easier to read, the caller of dwc3_prepare_one_trb() will determine if the TRB must have IOC bit set. This also reduces the number of times we need to call dwc3_calc_trbs_left(). Note that we only care about setting IOC from insufficient number of TRBs for SG and not linear requests (because we don't need to split linear requests). Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com> Signed-off-by: Felipe Balbi <balbi@kernel.org>
This commit is contained in:
parent
f9cc581bad
commit
8dbbe48c7a
|
@ -1034,8 +1034,7 @@ static void __dwc3_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_trb *trb,
|
||||||
trb->ctrl |= DWC3_TRB_CTRL_ISP_IMI;
|
trb->ctrl |= DWC3_TRB_CTRL_ISP_IMI;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((!no_interrupt && !chain) || must_interrupt ||
|
if ((!no_interrupt && !chain) || must_interrupt)
|
||||||
(dwc3_calc_trbs_left(dep) == 1))
|
|
||||||
trb->ctrl |= DWC3_TRB_CTRL_IOC;
|
trb->ctrl |= DWC3_TRB_CTRL_IOC;
|
||||||
|
|
||||||
if (chain)
|
if (chain)
|
||||||
|
@ -1169,6 +1168,7 @@ static int dwc3_prepare_trbs_sg(struct dwc3_ep *dep,
|
||||||
length -= sg_dma_len(s);
|
length -= sg_dma_len(s);
|
||||||
|
|
||||||
for_each_sg(sg, s, remaining, i) {
|
for_each_sg(sg, s, remaining, i) {
|
||||||
|
unsigned int num_trbs_left = dwc3_calc_trbs_left(dep);
|
||||||
unsigned int trb_length;
|
unsigned int trb_length;
|
||||||
bool must_interrupt = false;
|
bool must_interrupt = false;
|
||||||
bool last_sg = false;
|
bool last_sg = false;
|
||||||
|
@ -1187,7 +1187,7 @@ static int dwc3_prepare_trbs_sg(struct dwc3_ep *dep,
|
||||||
if ((i == remaining - 1) || !length)
|
if ((i == remaining - 1) || !length)
|
||||||
last_sg = true;
|
last_sg = true;
|
||||||
|
|
||||||
if (!dwc3_calc_trbs_left(dep))
|
if (!num_trbs_left)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (last_sg) {
|
if (last_sg) {
|
||||||
|
@ -1196,12 +1196,13 @@ static int dwc3_prepare_trbs_sg(struct dwc3_ep *dep,
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* Look ahead to check if we have enough TRBs for the
|
* Look ahead to check if we have enough TRBs for the
|
||||||
* last SG entry. If not, set interrupt on this TRB to
|
* next SG entry. If not, set interrupt on this TRB to
|
||||||
* resume preparing the last SG entry when more TRBs are
|
* resume preparing the next SG entry when more TRBs are
|
||||||
* free.
|
* free.
|
||||||
*/
|
*/
|
||||||
if (needs_extra_trb && dwc3_calc_trbs_left(dep) <= 2 &&
|
if (num_trbs_left == 1 || (needs_extra_trb &&
|
||||||
sg_dma_len(sg_next(s)) >= length)
|
num_trbs_left <= 2 &&
|
||||||
|
sg_dma_len(sg_next(s)) >= length))
|
||||||
must_interrupt = true;
|
must_interrupt = true;
|
||||||
|
|
||||||
dwc3_prepare_one_trb(dep, req, trb_length, 1, i, false,
|
dwc3_prepare_one_trb(dep, req, trb_length, 1, i, false,
|
||||||
|
@ -1230,7 +1231,7 @@ static int dwc3_prepare_trbs_sg(struct dwc3_ep *dep,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dwc3_calc_trbs_left(dep) || must_interrupt)
|
if (must_interrupt)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue