For OUT transfers, the total size (total TRB buffer allocation) must be
a multiple of MaxPacketSize even if software is expecting a fixed
non-multiple of MaxPacketSize transfer from the host.

(DWC_usb31 programming guide section 4.2.5)

So, to calculate the actual bytes written (OUT transfer), do:
actual = round_up(expected_length, MaxPacketSize) - remaining_length

Fixes: e62c5bc57367 ("usb: dwc3: gadget: tracking per-TRB remaining bytes")
Signed-off-by: Thinh Nguyen <thi...@synopsys.com>
---
 drivers/usb/dwc3/gadget.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index a5b8387a37ba..9859ca9dff9a 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -2319,6 +2319,8 @@ static int 
dwc3_gadget_ep_cleanup_completed_request(struct dwc3_ep *dep,
                const struct dwc3_event_depevt *event,
                struct dwc3_request *req, int status)
 {
+       unsigned int maxp = usb_endpoint_maxp(dep->endpoint.desc);
+       unsigned int length = req->request.length;
        int ret;
 
        if (req->num_pending_sgs)
@@ -2335,7 +2337,10 @@ static int 
dwc3_gadget_ep_cleanup_completed_request(struct dwc3_ep *dep,
                req->zero = false;
        }
 
-       req->request.actual = req->request.length - req->remaining;
+       if (usb_endpoint_dir_out(dep->endpoint.desc))
+               req->request.actual = round_up(length, maxp) - req->remaining;
+       else
+               req->request.actual = length - req->remaining;
 
        if (!dwc3_gadget_ep_request_completed(req) &&
                        req->num_pending_sgs) {
-- 
2.11.0

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to