usb: dwc3: gadget: Handle 0 xfer length for OUT EP
Hi,
Quoted 7 lines · Tejas Joglekar
For OUT endpoints, zero-length transfers require MaxPacketSize buffer as per the
DWC_usb3programming guide 3.30a section 4.2.3.3.This patch fixes this by explicitly checking zero length transfer to correctly pad up to MaxPacketSize.
Signed-off-by Tejas Joglekar <[email protected]>
do you have tracepoints of the problem?
Quoted 9 lines
--- drivers/usb/dwc3/gadget.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)drivers/usb/dwc3/gadget.c +0
-0
drivers/usb/dwc3/gadget.c static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep, · line 1073
Quoted 6 lines
drivers/usb/dwc3/gadget.c +2
-1@@ -1069,7 +1069,8 @@ static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep,if (sg_is_last (s)) chain = false; -if (rem &&usb_endpoint_dir_out (dep->endpoint.desc) && !chain) { +if ((!length || rem) &&usb_endpoint_dir_out (dep->endpoint.desc) + && !chain) {
are you 100% certain we have scatter/gather for a zlp? That doesn't make sense to me.
drivers/usb/dwc3/gadget.c static void dwc3_prepare_one_trb_linear(struct dwc3_ep *dep, · line 1118
Quoted 6 lines
drivers/usb/dwc3/gadget.c +1
-1@@ -1114,7 +1115,7 @@ static void dwc3_prepare_one_trb_linear(struct dwc3_ep *dep,unsigned int maxp =usb_endpoint_maxp (dep->endpoint.desc);unsigned int rem = length % maxp; -if (rem &&usb_endpoint_dir_out (dep->endpoint.desc)) { +if ((!length || rem) &&usb_endpoint_dir_out (dep->endpoint.desc)) {
this is already taken care of:
Quoted 8 lines
drivers/usb/dwc3/gadget.c +0
-0static void dwc3_prepare_one_trb_linear (struct dwc3_ep *dep,struct dwc3_request *req) {unsigned int length = req->request.length; unsigned int maxp = usb_endpoint_maxp(dep->endpoint.desc); unsigned int rem = length % maxp; if (rem && usb_endpoint_dir_out(dep->endpoint.desc)) {
[...]
Quoted 2 lines
} else if (req->request.zero && req->request.length &&
(IS_ALIGNED(req->request.length, maxp))) {why isn't this branch triggering for you? Please capture and share tracepoints exposing the problem
Quoted 19 lines
struct dwc3 *dwc = dep->dwc;
struct dwc3_trb *trb;
req->needs_extra_trb = true;
/* prepare normal TRB */
dwc3_prepare_one_trb(dep, req, true, 0);
/* Now 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->request.short_not_ok,
req->request.no_interrupt);
} else {
dwc3_prepare_one_trb(dep, req, false, 0);
}
}