usb: dwc3: gadget: Prevent queue on endpoints after bus reset
There is a race between ep_queue from function driver and ep_disable during function disable as part of bus reset. This race is leading to a scenario where the endpoint is disabled with an active transfer. And when the endpoint is enabled back, this leads to a stale buffer access by the controller. The race is as below: qdss_disable usb_qdss_write | -----> Waits on qdss_lock | ----> Acquires qdss_lock | | ----> Checks for qdss_connected | | ----> Releases qdss_lock | ------> Acquires qdss_lock | | ------> Clears usb_connected | | ------> Releases qdss_lock | usb_ep_disable | | ------> Acquires dwc->lock | dwc3_remove_reuests | | | dwc3_stop_active_transfer | | | | ------> Releases dwc->lock usb_ep_queue | | ----> Acquires dwc->lock usb_gadget_giveback | | dwc3_gadget_kick_transfer | | ----> Releases dwc->lock | | ----> Acquires dwc->lock | disable_endpoint After this state when the endpoint is enabled back, there is already and active transfer on this endpoint. Any START TRANSFER command on this endpoint would lead to "No Transfer Resource" error from the controller. Fix this by preventing the ep_queue when a reset of the gadget is in progress. This is done by clearing the connected flag as part of dwc3_gadget_reset and checking for this as part of ep_queue. Set this flag once we have received the CONNECTION DONE interrupt from the controller. Signed-off-by:Sriharsha Allenki <sallenki@codeaurora.org> Bug: 189997061 Bug: 203135867 Test: Build Pass Signed-off-by:
Jimmy Hu <hhhuuu@google.com> Signed-off-by:
Peggy Chan <peichi@google.com> Change-Id: Ieaab0b9a3025a224e0b68324de5f089ff402bfe4
Loading
Please register or sign in to comment