usb: dwc3: gadget: Fix handling ZLP
[ Upstream commitd2ee3ff79e
] The usb_request->zero doesn't apply for isoc. Also, if we prepare a 0-length (ZLP) TRB for the OUT direction, we need to prepare an extra TRB to pad up to the MPS alignment. Use the same bounce buffer for the ZLP TRB and the extra pad TRB. Cc: <stable@vger.kernel.org> # v4.5+ Fixes:d6e5a549cc
("usb: dwc3: simplify ZLP handling") Fixes:04c03d10e5
("usb: dwc3: gadget: handle request->zero") Signed-off-by: Thinh Nguyen <thinhn@synopsys.com> Signed-off-by: Felipe Balbi <balbi@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
4bc5d90a7d
commit
7c8b568566
|
@ -1159,6 +1159,7 @@ static void dwc3_prepare_one_trb_linear(struct dwc3_ep *dep,
|
|||
req->request.short_not_ok,
|
||||
req->request.no_interrupt);
|
||||
} else if (req->request.zero && req->request.length &&
|
||||
!usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
|
||||
(IS_ALIGNED(req->request.length, maxp))) {
|
||||
struct dwc3 *dwc = dep->dwc;
|
||||
struct dwc3_trb *trb;
|
||||
|
@ -1168,13 +1169,23 @@ static void dwc3_prepare_one_trb_linear(struct dwc3_ep *dep,
|
|||
/* prepare normal TRB */
|
||||
dwc3_prepare_one_trb(dep, req, length, true, 0);
|
||||
|
||||
/* Now prepare one extra TRB to handle ZLP */
|
||||
/* Prepare one extra TRB to handle ZLP */
|
||||
trb = &dep->trb_pool[dep->trb_enqueue];
|
||||
req->num_trbs++;
|
||||
__dwc3_prepare_one_trb(dep, trb, dwc->bounce_addr, 0,
|
||||
false, 1, req->request.stream_id,
|
||||
!req->direction, 1, req->request.stream_id,
|
||||
req->request.short_not_ok,
|
||||
req->request.no_interrupt);
|
||||
|
||||
/* Prepare one more TRB to handle MPS alignment for OUT */
|
||||
if (!req->direction) {
|
||||
trb = &dep->trb_pool[dep->trb_enqueue];
|
||||
req->num_trbs++;
|
||||
__dwc3_prepare_one_trb(dep, trb, dwc->bounce_addr, maxp,
|
||||
false, 1, req->request.stream_id,
|
||||
req->request.short_not_ok,
|
||||
req->request.no_interrupt);
|
||||
}
|
||||
} else {
|
||||
dwc3_prepare_one_trb(dep, req, length, false, 0);
|
||||
}
|
||||
|
@ -2578,8 +2589,17 @@ static int dwc3_gadget_ep_cleanup_completed_request(struct dwc3_ep *dep,
|
|||
status);
|
||||
|
||||
if (req->needs_extra_trb) {
|
||||
unsigned int maxp = usb_endpoint_maxp(dep->endpoint.desc);
|
||||
|
||||
ret = dwc3_gadget_ep_reclaim_trb_linear(dep, req, event,
|
||||
status);
|
||||
|
||||
/* Reclaim MPS padding TRB for ZLP */
|
||||
if (!req->direction && req->request.zero && req->request.length &&
|
||||
!usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
|
||||
(IS_ALIGNED(req->request.length, maxp)))
|
||||
ret = dwc3_gadget_ep_reclaim_trb_linear(dep, req, event, status);
|
||||
|
||||
req->needs_extra_trb = false;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue