lkml.org 
[lkml]   [2020]   [Nov]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.4 139/214] usb: dwc3: gadget: Resume pending requests after CLEAR_STALL
    Date
    From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>

    commit c503672abe1348f10f5a54a662336358c6e1a297 upstream.

    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: cb11ea56f37a ("usb: dwc3: gadget: Properly handle ClearFeature(halt)")
    Signed-off-by: Thinh Nguyen <thinhn@synopsys.com>
    Signed-off-by: Felipe Balbi <balbi@kernel.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/usb/dwc3/gadget.c | 22 ++++++++++++++--------
    1 file changed, 14 insertions(+), 8 deletions(-)

    --- a/drivers/usb/dwc3/gadget.c
    +++ b/drivers/usb/dwc3/gadget.c
    @@ -1521,8 +1521,13 @@ static int __dwc3_gadget_ep_queue(struct
    list_add_tail(&req->list, &dep->pending_list);
    req->status = DWC3_REQUEST_STATUS_QUEUED;

    - /* 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;
    }
    @@ -1728,13 +1733,14 @@ int __dwc3_gadget_ep_set_halt(struct dwc
    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;

    \
     
     \ /
      Last update: 2020-11-03 22:31    [W:4.144 / U:1.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site