|
Oliver Neukum |
73a340 |
From c7428dbddcf4ea1919e1c8e15f715b94ca359268 Mon Sep 17 00:00:00 2001
|
|
Oliver Neukum |
73a340 |
From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
|
|
Oliver Neukum |
73a340 |
Date: Fri, 22 Apr 2022 17:36:28 -0700
|
|
Oliver Neukum |
73a340 |
Subject: [PATCH] usb: dwc3: gadget: Return proper request status
|
|
Oliver Neukum |
73a340 |
Git-commit: c7428dbddcf4ea1919e1c8e15f715b94ca359268
|
|
Oliver Neukum |
73a340 |
References: git-fixes
|
|
Oliver Neukum |
73a340 |
Patch-mainline: v5.18-rc5
|
|
Oliver Neukum |
73a340 |
|
|
Oliver Neukum |
73a340 |
If the user sets the usb_request's no_interrupt, then there will be no
|
|
Oliver Neukum |
73a340 |
completion event for the request. Currently the driver incorrectly uses
|
|
Oliver Neukum |
73a340 |
the event status of a different request to report the status for a
|
|
Oliver Neukum |
73a340 |
request with no_interrupt. The dwc3 driver needs to check the TRB status
|
|
Oliver Neukum |
73a340 |
associated with the request when reporting its status.
|
|
Oliver Neukum |
73a340 |
|
|
Oliver Neukum |
73a340 |
Note: this is only applicable to missed_isoc TRB completion status, but
|
|
Oliver Neukum |
73a340 |
the other status are also listed for completeness/documentation.
|
|
Oliver Neukum |
73a340 |
|
|
Oliver Neukum |
73a340 |
Fixes: 6d8a019614f3 ("usb: dwc3: gadget: check for Missed Isoc from event status")
|
|
Oliver Neukum |
73a340 |
Cc: <stable@vger.kernel.org>
|
|
Oliver Neukum |
73a340 |
Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
|
|
Oliver Neukum |
73a340 |
Link: https://lore.kernel.org/r/db2c80108286cfd108adb05bad52138b78d7c3a7.1650673655.git.Thinh.Nguyen@synopsys.com
|
|
Oliver Neukum |
73a340 |
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
Oliver Neukum |
73a340 |
Signed-off-by: Oliver Neukum <oneukum@suse.com>
|
|
Oliver Neukum |
73a340 |
---
|
|
Oliver Neukum |
73a340 |
drivers/usb/dwc3/gadget.c | 31 ++++++++++++++++++++++++++++++-
|
|
Oliver Neukum |
73a340 |
1 file changed, 30 insertions(+), 1 deletion(-)
|
|
Oliver Neukum |
73a340 |
|
|
Oliver Neukum |
73a340 |
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
|
|
Oliver Neukum |
73a340 |
index ab725d2262d6..0b9c2493844a 100644
|
|
Oliver Neukum |
73a340 |
--- a/drivers/usb/dwc3/gadget.c
|
|
Oliver Neukum |
73a340 |
+++ b/drivers/usb/dwc3/gadget.c
|
|
Oliver Neukum |
73a340 |
@@ -3274,6 +3274,7 @@ static int dwc3_gadget_ep_cleanup_completed_request(struct dwc3_ep *dep,
|
|
Oliver Neukum |
73a340 |
const struct dwc3_event_depevt *event,
|
|
Oliver Neukum |
73a340 |
struct dwc3_request *req, int status)
|
|
Oliver Neukum |
73a340 |
{
|
|
Oliver Neukum |
73a340 |
+ int request_status;
|
|
Oliver Neukum |
73a340 |
int ret;
|
|
Oliver Neukum |
73a340 |
|
|
Oliver Neukum |
73a340 |
if (req->request.num_mapped_sgs)
|
|
Oliver Neukum |
73a340 |
@@ -3294,7 +3295,35 @@ static int dwc3_gadget_ep_cleanup_completed_request(struct dwc3_ep *dep,
|
|
Oliver Neukum |
73a340 |
req->needs_extra_trb = false;
|
|
Oliver Neukum |
73a340 |
}
|
|
Oliver Neukum |
73a340 |
|
|
Oliver Neukum |
73a340 |
- dwc3_gadget_giveback(dep, req, status);
|
|
Oliver Neukum |
73a340 |
+ /*
|
|
Oliver Neukum |
73a340 |
+ * The event status only reflects the status of the TRB with IOC set.
|
|
Oliver Neukum |
73a340 |
+ * For the requests that don't set interrupt on completion, the driver
|
|
Oliver Neukum |
73a340 |
+ * needs to check and return the status of the completed TRBs associated
|
|
Oliver Neukum |
73a340 |
+ * with the request. Use the status of the last TRB of the request.
|
|
Oliver Neukum |
73a340 |
+ */
|
|
Oliver Neukum |
73a340 |
+ if (req->request.no_interrupt) {
|
|
Oliver Neukum |
73a340 |
+ struct dwc3_trb *trb;
|
|
Oliver Neukum |
73a340 |
+
|
|
Oliver Neukum |
73a340 |
+ trb = dwc3_ep_prev_trb(dep, dep->trb_dequeue);
|
|
Oliver Neukum |
73a340 |
+ switch (DWC3_TRB_SIZE_TRBSTS(trb->size)) {
|
|
Oliver Neukum |
73a340 |
+ case DWC3_TRBSTS_MISSED_ISOC:
|
|
Oliver Neukum |
73a340 |
+ /* Isoc endpoint only */
|
|
Oliver Neukum |
73a340 |
+ request_status = -EXDEV;
|
|
Oliver Neukum |
73a340 |
+ break;
|
|
Oliver Neukum |
73a340 |
+ case DWC3_TRB_STS_XFER_IN_PROG:
|
|
Oliver Neukum |
73a340 |
+ /* Applicable when End Transfer with ForceRM=0 */
|
|
Oliver Neukum |
73a340 |
+ case DWC3_TRBSTS_SETUP_PENDING:
|
|
Oliver Neukum |
73a340 |
+ /* Control endpoint only */
|
|
Oliver Neukum |
73a340 |
+ case DWC3_TRBSTS_OK:
|
|
Oliver Neukum |
73a340 |
+ default:
|
|
Oliver Neukum |
73a340 |
+ request_status = 0;
|
|
Oliver Neukum |
73a340 |
+ break;
|
|
Oliver Neukum |
73a340 |
+ }
|
|
Oliver Neukum |
73a340 |
+ } else {
|
|
Oliver Neukum |
73a340 |
+ request_status = status;
|
|
Oliver Neukum |
73a340 |
+ }
|
|
Oliver Neukum |
73a340 |
+
|
|
Oliver Neukum |
73a340 |
+ dwc3_gadget_giveback(dep, req, request_status);
|
|
Oliver Neukum |
73a340 |
|
|
Oliver Neukum |
73a340 |
out:
|
|
Oliver Neukum |
73a340 |
return ret;
|
|
Oliver Neukum |
73a340 |
--
|
|
Oliver Neukum |
73a340 |
2.35.3
|
|
Oliver Neukum |
73a340 |
|