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.9 240/391] usb: dwc3: ep0: Fix ZLP for OUT ep0 requests
    Date
    From: Thinh Nguyen <Thinh.Nguyen@synopsys.com>

    commit 66706077dc89c66a4777a4c6298273816afb848c upstream.

    The current ZLP handling for ep0 requests is only for control IN
    requests. For OUT direction, DWC3 needs to check and setup for MPS
    alignment.

    Usually, control OUT requests can indicate its transfer size via the
    wLength field of the control message. So usb_request->zero is usually
    not needed for OUT direction. To handle ZLP OUT for control endpoint,
    make sure the TRB is MPS size.

    Cc: stable@vger.kernel.org
    Fixes: c7fcdeb2627c ("usb: dwc3: ep0: simplify EP0 state machine")
    Fixes: d6e5a549cc4d ("usb: dwc3: simplify ZLP handling")
    Signed-off-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
    Signed-off-by: Felipe Balbi <balbi@kernel.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/usb/dwc3/ep0.c | 11 +++++++++--
    1 file changed, 9 insertions(+), 2 deletions(-)

    --- a/drivers/usb/dwc3/ep0.c
    +++ b/drivers/usb/dwc3/ep0.c
    @@ -942,12 +942,16 @@ static void dwc3_ep0_xfer_complete(struc
    static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
    struct dwc3_ep *dep, struct dwc3_request *req)
    {
    + unsigned int trb_length = 0;
    int ret;

    req->direction = !!dep->number;

    if (req->request.length == 0) {
    - dwc3_ep0_prepare_one_trb(dep, dwc->ep0_trb_addr, 0,
    + if (!req->direction)
    + trb_length = dep->endpoint.maxpacket;
    +
    + dwc3_ep0_prepare_one_trb(dep, dwc->bounce_addr, trb_length,
    DWC3_TRBCTL_CONTROL_DATA, false);
    ret = dwc3_ep0_start_trans(dep);
    } else if (!IS_ALIGNED(req->request.length, dep->endpoint.maxpacket)
    @@ -994,9 +998,12 @@ static void __dwc3_ep0_do_control_data(s

    req->trb = &dwc->ep0_trb[dep->trb_enqueue - 1];

    + if (!req->direction)
    + trb_length = dep->endpoint.maxpacket;
    +
    /* Now prepare one extra TRB to align transfer size */
    dwc3_ep0_prepare_one_trb(dep, dwc->bounce_addr,
    - 0, DWC3_TRBCTL_CONTROL_DATA,
    + trb_length, DWC3_TRBCTL_CONTROL_DATA,
    false);
    ret = dwc3_ep0_start_trans(dep);
    } else {

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