lkml.org 
[lkml]   [2020]   [Jun]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.19 067/206] usb: dwc3: gadget: Properly handle failed kick_transfer
    Date
    From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>

    [ Upstream commit 8d99087c2db863c5fa3a4a1f3cb82b3a493705ca ]

    If dwc3 fails to issue START_TRANSFER/UPDATE_TRANSFER command, then we
    should properly end an active transfer and give back all the started
    requests. However if it's for an isoc endpoint, the failure maybe due to
    bus-expiry status. In this case, don't give back the requests and wait
    for the next retry.

    Fixes: 72246da40f37 ("usb: Introduce DesignWare USB3 DRD Driver")
    Signed-off-by: Thinh Nguyen <thinhn@synopsys.com>
    Signed-off-by: Felipe Balbi <balbi@kernel.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/usb/dwc3/gadget.c | 24 ++++++++++++++++--------
    1 file changed, 16 insertions(+), 8 deletions(-)

    diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
    index 8e66954dfcd4e..2f5f4ca5c0d04 100644
    --- a/drivers/usb/dwc3/gadget.c
    +++ b/drivers/usb/dwc3/gadget.c
    @@ -1217,6 +1217,8 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep)
    }
    }

    +static void dwc3_gadget_ep_cleanup_cancelled_requests(struct dwc3_ep *dep);
    +
    static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep)
    {
    struct dwc3_gadget_ep_cmd_params params;
    @@ -1253,14 +1255,20 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep)

    ret = dwc3_send_gadget_ep_cmd(dep, cmd, &params);
    if (ret < 0) {
    - /*
    - * FIXME we need to iterate over the list of requests
    - * here and stop, unmap, free and del each of the linked
    - * requests instead of what we do now.
    - */
    - if (req->trb)
    - memset(req->trb, 0, sizeof(struct dwc3_trb));
    - dwc3_gadget_del_and_unmap_request(dep, req, ret);
    + struct dwc3_request *tmp;
    +
    + if (ret == -EAGAIN)
    + return ret;
    +
    + dwc3_stop_active_transfer(dep, true, true);
    +
    + list_for_each_entry_safe(req, tmp, &dep->started_list, list)
    + dwc3_gadget_move_cancelled_request(req);
    +
    + /* If ep isn't started, then there's no end transfer pending */
    + if (!(dep->flags & DWC3_EP_END_TRANSFER_PENDING))
    + dwc3_gadget_ep_cleanup_cancelled_requests(dep);
    +
    return ret;
    }

    --
    2.25.1


    \
     
     \ /
      Last update: 2020-06-23 22:39    [W:4.035 / U:0.900 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site