From 92de566762db61b138765a26e4afaacc7d7f7816 Mon Sep 17 00:00:00 2001 From: Ray Chi Date: Wed, 17 Mar 2021 19:47:31 +0800 Subject: [PATCH] ANDROID: usb: dwc3: gadget: don't cancel the started requests Currently, there is an application on Mac that it will send ClearFeature(halt_ep) request before transfering USB data. If the device receives the ClearFeature(halt_ep) request, the started requests would be removed and restart the transfer. However, userspace services don't know this behavior. The services will free the requests instead of retry and resend the requests. It will cause the USB host can't get response so that it will try to recover by issuing a reset signal. Finally, it will take the infinite loop. send reqeust > reset > re-enumeration > send request > reset > ... To avoid this symptom, this patch will keep the started requests so that userspace services didn't free the requests. Bug: 178904115 Bug: 177879761 Signed-off-by: Ray Chi Change-Id: I52acf48871fd7f86cfcc51fb41c67d21ea895d69 Signed-off-by: Saravana Kannan --- drivers/usb/dwc3/gadget.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index d1e1a0af13af..b760c91747e5 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1811,8 +1811,6 @@ int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value, int protocol) { struct dwc3_gadget_ep_cmd_params params; struct dwc3 *dwc = dep->dwc; - struct dwc3_request *req; - struct dwc3_request *tmp; int ret; if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) { @@ -1861,16 +1859,14 @@ int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value, int protocol) dwc3_stop_active_transfer(dep, true, true); - list_for_each_entry_safe(req, tmp, &dep->started_list, list) - dwc3_gadget_move_cancelled_request(req, DWC3_REQUEST_STATUS_STALLED); + if (!list_empty(&dep->started_list)) + dep->flags |= DWC3_EP_DELAY_START; if (dep->flags & DWC3_EP_END_TRANSFER_PENDING) { dep->flags |= DWC3_EP_PENDING_CLEAR_STALL; return 0; } - dwc3_gadget_ep_cleanup_cancelled_requests(dep); - ret = dwc3_send_clear_stall_ep_cmd(dep); if (ret) { dev_err(dwc->dev, "failed to clear STALL on %s\n",