Skip to content

Commit

Permalink
usb: dwc3: gadget: Resume pending requests after CLEAR_STALL
Browse files Browse the repository at this point in the history
The function driver may queue new requests right after halting the
endpoint (i.e. queue new requests while the endpoint is stalled).
There's no restriction preventing it from doing so. However, dwc3
currently drops those requests after CLEAR_STALL. The driver should only
drop started requests. Keep the pending requests in the pending list to
resume and process them after the host issues ClearFeature(Halt) to the
endpoint.

Cc: stable@vger.kernel.org
Fixes: cb11ea5 ("usb: dwc3: gadget: Properly handle ClearFeature(halt)")
Signed-off-by: Thinh Nguyen <thinhn@synopsys.com>
Signed-off-by: Felipe Balbi <balbi@kernel.org>
  • Loading branch information
Thinh Nguyen authored and Felipe Balbi committed Sep 24, 2020
1 parent ba4f184 commit c503672
Showing 1 changed file with 14 additions and 8 deletions.
22 changes: 14 additions & 8 deletions drivers/usb/dwc3/gadget.c
Original file line number Diff line number Diff line change
Expand Up @@ -1628,8 +1628,13 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
if (dep->flags & DWC3_EP_WAIT_TRANSFER_COMPLETE)
return 0;

/* Start the transfer only after the END_TRANSFER is completed */
if (dep->flags & DWC3_EP_END_TRANSFER_PENDING) {
/*
* Start the transfer only after the END_TRANSFER is completed
* and endpoint STALL is cleared.
*/
if ((dep->flags & DWC3_EP_END_TRANSFER_PENDING) ||
(dep->flags & DWC3_EP_WEDGE) ||
(dep->flags & DWC3_EP_STALL)) {
dep->flags |= DWC3_EP_DELAY_START;
return 0;
}
Expand Down Expand Up @@ -1836,13 +1841,14 @@ int __dwc3_gadget_ep_set_halt(struct dwc3_ep *dep, int value, int protocol)
list_for_each_entry_safe(req, tmp, &dep->started_list, list)
dwc3_gadget_move_cancelled_request(req);

list_for_each_entry_safe(req, tmp, &dep->pending_list, list)
dwc3_gadget_move_cancelled_request(req);

if (!(dep->flags & DWC3_EP_END_TRANSFER_PENDING)) {
dep->flags &= ~DWC3_EP_DELAY_START;
if (!(dep->flags & DWC3_EP_END_TRANSFER_PENDING))
dwc3_gadget_ep_cleanup_cancelled_requests(dep);
}

if ((dep->flags & DWC3_EP_DELAY_START) &&
!usb_endpoint_xfer_isoc(dep->endpoint.desc))
__dwc3_gadget_kick_transfer(dep);

dep->flags &= ~DWC3_EP_DELAY_START;
}

return ret;
Expand Down

0 comments on commit c503672

Please sign in to comment.