UPSTREAM: usb: dwc3: gadget: use allocated/queued reqs for LST bit
[firefly-linux-kernel-4.4.55.git] / drivers / usb / dwc3 / ep0.c
index 5acbb948b7048ffb22c6e921e93f6617bec1cbe7..763fac772398436c8b53e755367436c64c69bd39 100644 (file)
@@ -6,34 +6,14 @@
  * Authors: Felipe Balbi <balbi@ti.com>,
  *         Sebastian Andrzej Siewior <bigeasy@linutronix.de>
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions, and the following disclaimer,
- *    without modification.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The names of the above-listed copyright holders may not be used
- *    to endorse or promote products derived from this software without
- *    specific prior written permission.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2  of
+ * the License as published by the Free Software Foundation.
  *
- * ALTERNATIVELY, this software may be distributed under the terms of the
- * GNU General Public License ("GPL") version 2, as published by the Free
- * Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
  */
 
 #include <linux/kernel.h>
@@ -51,6 +31,7 @@
 #include <linux/usb/composite.h>
 
 #include "core.h"
+#include "debug.h"
 #include "gadget.h"
 #include "io.h"
 
@@ -75,7 +56,7 @@ static const char *dwc3_ep0_state_string(enum dwc3_ep0_state state)
 }
 
 static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma,
-               u32 len, u32 type)
+               u32 len, u32 type, bool chain)
 {
        struct dwc3_gadget_ep_cmd_params params;
        struct dwc3_trb                 *trb;
@@ -85,11 +66,14 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma,
 
        dep = dwc->eps[epnum];
        if (dep->flags & DWC3_EP_BUSY) {
-               dev_vdbg(dwc->dev, "%s: still busy\n", dep->name);
+               dwc3_trace(trace_dwc3_ep0, "%s still busy", dep->name);
                return 0;
        }
 
-       trb = dwc->ep0_trb;
+       trb = &dwc->ep0_trb[dep->trb_enqueue];
+
+       if (chain)
+               dep->trb_enqueue++;
 
        trb->bpl = lower_32_bits(buf_dma);
        trb->bph = upper_32_bits(buf_dma);
@@ -97,25 +81,32 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma,
        trb->ctrl = type;
 
        trb->ctrl |= (DWC3_TRB_CTRL_HWO
-                       | DWC3_TRB_CTRL_LST
-                       | DWC3_TRB_CTRL_IOC
                        | DWC3_TRB_CTRL_ISP_IMI);
 
+       if (chain)
+               trb->ctrl |= DWC3_TRB_CTRL_CHN;
+       else
+               trb->ctrl |= (DWC3_TRB_CTRL_IOC
+                               | DWC3_TRB_CTRL_LST);
+
+       if (chain)
+               return 0;
+
        memset(&params, 0, sizeof(params));
        params.param0 = upper_32_bits(dwc->ep0_trb_addr);
        params.param1 = lower_32_bits(dwc->ep0_trb_addr);
 
-       ret = dwc3_send_gadget_ep_cmd(dwc, dep->number,
-                       DWC3_DEPCMD_STARTTRANSFER, &params);
+       trace_dwc3_prepare_trb(dep, trb);
+
+       ret = dwc3_send_gadget_ep_cmd(dep, DWC3_DEPCMD_STARTTRANSFER, &params);
        if (ret < 0) {
-               dev_dbg(dwc->dev, "failed to send STARTTRANSFER command\n");
+               dwc3_trace(trace_dwc3_ep0, "%s STARTTRANSFER failed",
+                               dep->name);
                return ret;
        }
 
        dep->flags |= DWC3_EP_BUSY;
-       dep->resource_index = dwc3_gadget_ep_get_transfer_index(dwc,
-                       dep->number);
-
+       dep->resource_index = dwc3_gadget_ep_get_transfer_index(dep);
        dwc->ep0_next_event = DWC3_EP0_COMPLETE;
 
        return 0;
@@ -130,7 +121,7 @@ static int __dwc3_gadget_ep0_queue(struct dwc3_ep *dep,
        req->request.status     = -EINPROGRESS;
        req->epnum              = dep->number;
 
-       list_add_tail(&req->list, &dep->request_list);
+       list_add_tail(&req->list, &dep->pending_list);
 
        /*
         * Gadget driver might not be quick enough to queue a request
@@ -168,11 +159,13 @@ static int __dwc3_gadget_ep0_queue(struct dwc3_ep *dep,
 
                direction = !dwc->ep0_expect_in;
                dwc->delayed_status = false;
+               usb_gadget_set_state(&dwc->gadget, USB_STATE_CONFIGURED);
 
                if (dwc->ep0state == EP0_STATUS_PHASE)
                        __dwc3_ep0_do_control_status(dwc, dwc->eps[direction]);
                else
-                       dev_dbg(dwc->dev, "too early for delayed status\n");
+                       dwc3_trace(trace_dwc3_ep0,
+                                       "too early for delayed status");
 
                return 0;
        }
@@ -236,19 +229,21 @@ int dwc3_gadget_ep0_queue(struct usb_ep *ep, struct usb_request *request,
 
        spin_lock_irqsave(&dwc->lock, flags);
        if (!dep->endpoint.desc) {
-               dev_dbg(dwc->dev, "trying to queue request %p to disabled %s\n",
+               dwc3_trace(trace_dwc3_ep0,
+                               "trying to queue request %p to disabled %s",
                                request, dep->name);
                ret = -ESHUTDOWN;
                goto out;
        }
 
        /* we share one TRB for ep0/1 */
-       if (!list_empty(&dep->request_list)) {
+       if (!list_empty(&dep->pending_list)) {
                ret = -EBUSY;
                goto out;
        }
 
-       dev_vdbg(dwc->dev, "queueing request %p to %s length %d, state '%s'\n",
+       dwc3_trace(trace_dwc3_ep0,
+                       "queueing request %p to %s length %d state '%s'",
                        request, dep->name, request->length,
                        dwc3_ep0_state_string(dwc->ep0state));
 
@@ -270,14 +265,14 @@ static void dwc3_ep0_stall_and_restart(struct dwc3 *dwc)
 
        /* stall is always issued on EP0 */
        dep = dwc->eps[0];
-       __dwc3_gadget_ep_set_halt(dep, 1);
+       __dwc3_gadget_ep_set_halt(dep, 1, false);
        dep->flags = DWC3_EP_ENABLED;
        dwc->delayed_status = false;
 
-       if (!list_empty(&dep->request_list)) {
+       if (!list_empty(&dep->pending_list)) {
                struct dwc3_request     *req;
 
-               req = next_request(&dep->request_list);
+               req = next_request(&dep->pending_list);
                dwc3_gadget_giveback(dep, req, -ECONNRESET);
        }
 
@@ -285,7 +280,7 @@ static void dwc3_ep0_stall_and_restart(struct dwc3 *dwc)
        dwc3_ep0_out_start(dwc);
 }
 
-int dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value)
+int __dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value)
 {
        struct dwc3_ep                  *dep = to_dwc3_ep(ep);
        struct dwc3                     *dwc = dep->dwc;
@@ -295,12 +290,26 @@ int dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value)
        return 0;
 }
 
+int dwc3_gadget_ep0_set_halt(struct usb_ep *ep, int value)
+{
+       struct dwc3_ep                  *dep = to_dwc3_ep(ep);
+       struct dwc3                     *dwc = dep->dwc;
+       unsigned long                   flags;
+       int                             ret;
+
+       spin_lock_irqsave(&dwc->lock, flags);
+       ret = __dwc3_gadget_ep0_set_halt(ep, value);
+       spin_unlock_irqrestore(&dwc->lock, flags);
+
+       return ret;
+}
+
 void dwc3_ep0_out_start(struct dwc3 *dwc)
 {
        int                             ret;
 
        ret = dwc3_ep0_start_trans(dwc, 0, dwc->ctrl_req_addr, 8,
-                       DWC3_TRBCTL_CONTROL_SETUP);
+                       DWC3_TRBCTL_CONTROL_SETUP, false);
        WARN_ON(ret < 0);
 }
 
@@ -342,7 +351,7 @@ static int dwc3_ep0_handle_status(struct dwc3 *dwc,
                /*
                 * LTM will be set once we know how to set this in HW.
                 */
-               usb_status |= dwc->is_selfpowered << USB_DEVICE_SELF_POWERED;
+               usb_status |= dwc->gadget.is_selfpowered;
 
                if (dwc->speed == DWC3_DSTS_SUPERSPEED) {
                        reg = dwc3_readl(dwc->regs, DWC3_DCTL);
@@ -371,7 +380,7 @@ static int dwc3_ep0_handle_status(struct dwc3 *dwc,
                break;
        default:
                return -EINVAL;
-       };
+       }
 
        response_pkt = (__le16 *) dwc->setup_buf;
        *response_pkt = cpu_to_le16(usb_status);
@@ -441,7 +450,6 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc,
 
                case USB_DEVICE_LTM_ENABLE:
                        return -EINVAL;
-                       break;
 
                case USB_DEVICE_TEST_MODE:
                        if ((wIndex & 0xff) != 0)
@@ -449,8 +457,18 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc,
                        if (!set)
                                return -EINVAL;
 
-                       dwc->test_mode_nr = wIndex >> 8;
-                       dwc->test_mode = true;
+                       switch (wIndex >> 8) {
+                       case TEST_J:
+                       case TEST_K:
+                       case TEST_SE0_NAK:
+                       case TEST_PACKET:
+                       case TEST_FORCE_EN:
+                               dwc->test_mode_nr = wIndex >> 8;
+                               dwc->test_mode = true;
+                               break;
+                       default:
+                               return -EINVAL;
+                       }
                        break;
                default:
                        return -EINVAL;
@@ -475,10 +493,12 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc,
        case USB_RECIP_ENDPOINT:
                switch (wValue) {
                case USB_ENDPOINT_HALT:
-                       dep = dwc3_wIndex_to_dep(dwc, wIndex);
+                       dep = dwc3_wIndex_to_dep(dwc, ctrl->wIndex);
                        if (!dep)
                                return -EINVAL;
-                       ret = __dwc3_gadget_ep_set_halt(dep, set);
+                       if (set == 0 && (dep->flags & DWC3_EP_WEDGE))
+                               break;
+                       ret = __dwc3_gadget_ep_set_halt(dep, set, true);
                        if (ret)
                                return -EINVAL;
                        break;
@@ -489,7 +509,7 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc,
 
        default:
                return -EINVAL;
-       };
+       }
 
        return 0;
 }
@@ -502,12 +522,13 @@ static int dwc3_ep0_set_address(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
 
        addr = le16_to_cpu(ctrl->wValue);
        if (addr > 127) {
-               dev_dbg(dwc->dev, "invalid device address %d\n", addr);
+               dwc3_trace(trace_dwc3_ep0, "invalid device address %d", addr);
                return -EINVAL;
        }
 
        if (state == USB_STATE_CONFIGURED) {
-               dev_dbg(dwc->dev, "trying to set address when configured\n");
+               dwc3_trace(trace_dwc3_ep0,
+                               "trying to set address when configured");
                return -EINVAL;
        }
 
@@ -541,20 +562,26 @@ static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
        int ret;
        u32 reg;
 
-       dwc->start_config_issued = false;
        cfg = le16_to_cpu(ctrl->wValue);
 
        switch (state) {
        case USB_STATE_DEFAULT:
                return -EINVAL;
-               break;
 
        case USB_STATE_ADDRESS:
                ret = dwc3_ep0_delegate_req(dwc, ctrl);
                /* if the cfg matches and the cfg is non zero */
                if (cfg && (!ret || (ret == USB_GADGET_DELAYED_STATUS))) {
-                       usb_gadget_set_state(&dwc->gadget,
-                                       USB_STATE_CONFIGURED);
+
+                       /*
+                        * only change state if set_config has already
+                        * been processed. If gadget driver returns
+                        * USB_GADGET_DELAYED_STATUS, we will wait
+                        * to change the state on the next usb_ep_queue()
+                        */
+                       if (ret == 0)
+                               usb_gadget_set_state(&dwc->gadget,
+                                               USB_STATE_CONFIGURED);
 
                        /*
                         * Enable transition to U1/U2 state when
@@ -563,15 +590,12 @@ static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
                        reg = dwc3_readl(dwc->regs, DWC3_DCTL);
                        reg |= (DWC3_DCTL_ACCEPTU1ENA | DWC3_DCTL_ACCEPTU2ENA);
                        dwc3_writel(dwc->regs, DWC3_DCTL, reg);
-
-                       dwc->resize_fifos = true;
-                       dev_dbg(dwc->dev, "resize fifos flag SET\n");
                }
                break;
 
        case USB_STATE_CONFIGURED:
                ret = dwc3_ep0_delegate_req(dwc, ctrl);
-               if (!cfg)
+               if (!cfg && !ret)
                        usb_gadget_set_state(&dwc->gadget,
                                        USB_STATE_ADDRESS);
                break;
@@ -592,8 +616,8 @@ static void dwc3_ep0_set_sel_cmpl(struct usb_ep *ep, struct usb_request *req)
        struct timing {
                u8      u1sel;
                u8      u1pel;
-               u16     u2sel;
-               u16     u2pel;
+               __le16  u2sel;
+               __le16  u2pel;
        } __packed timing;
 
        int             ret;
@@ -689,38 +713,38 @@ static int dwc3_ep0_std_request(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
 
        switch (ctrl->bRequest) {
        case USB_REQ_GET_STATUS:
-               dev_vdbg(dwc->dev, "USB_REQ_GET_STATUS\n");
+               dwc3_trace(trace_dwc3_ep0, "USB_REQ_GET_STATUS");
                ret = dwc3_ep0_handle_status(dwc, ctrl);
                break;
        case USB_REQ_CLEAR_FEATURE:
-               dev_vdbg(dwc->dev, "USB_REQ_CLEAR_FEATURE\n");
+               dwc3_trace(trace_dwc3_ep0, "USB_REQ_CLEAR_FEATURE");
                ret = dwc3_ep0_handle_feature(dwc, ctrl, 0);
                break;
        case USB_REQ_SET_FEATURE:
-               dev_vdbg(dwc->dev, "USB_REQ_SET_FEATURE\n");
+               dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_FEATURE");
                ret = dwc3_ep0_handle_feature(dwc, ctrl, 1);
                break;
        case USB_REQ_SET_ADDRESS:
-               dev_vdbg(dwc->dev, "USB_REQ_SET_ADDRESS\n");
+               dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_ADDRESS");
                ret = dwc3_ep0_set_address(dwc, ctrl);
                break;
        case USB_REQ_SET_CONFIGURATION:
-               dev_vdbg(dwc->dev, "USB_REQ_SET_CONFIGURATION\n");
+               dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_CONFIGURATION");
                ret = dwc3_ep0_set_config(dwc, ctrl);
                break;
        case USB_REQ_SET_SEL:
-               dev_vdbg(dwc->dev, "USB_REQ_SET_SEL\n");
+               dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_SEL");
                ret = dwc3_ep0_set_sel(dwc, ctrl);
                break;
        case USB_REQ_SET_ISOCH_DELAY:
-               dev_vdbg(dwc->dev, "USB_REQ_SET_ISOCH_DELAY\n");
+               dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_ISOCH_DELAY");
                ret = dwc3_ep0_set_isoch_delay(dwc, ctrl);
                break;
        default:
-               dev_vdbg(dwc->dev, "Forwarding to gadget driver\n");
+               dwc3_trace(trace_dwc3_ep0, "Forwarding to gadget driver");
                ret = dwc3_ep0_delegate_req(dwc, ctrl);
                break;
-       };
+       }
 
        return ret;
 }
@@ -735,6 +759,8 @@ static void dwc3_ep0_inspect_setup(struct dwc3 *dwc,
        if (!dwc->gadget_driver)
                goto out;
 
+       trace_dwc3_ctrl_req(ctrl);
+
        len = le16_to_cpu(ctrl->wLength);
        if (!len) {
                dwc->three_stage_setup = false;
@@ -766,7 +792,11 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
        struct usb_request      *ur;
        struct dwc3_trb         *trb;
        struct dwc3_ep          *ep0;
-       u32                     transferred;
+       unsigned                transfer_size = 0;
+       unsigned                maxp;
+       unsigned                remaining_ur_length;
+       void                    *buf;
+       u32                     transferred = 0;
        u32                     status;
        u32                     length;
        u8                      epnum;
@@ -776,14 +806,19 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
 
        dwc->ep0_next_event = DWC3_EP0_NRDY_STATUS;
 
-       r = next_request(&ep0->request_list);
-       ur = &r->request;
-
        trb = dwc->ep0_trb;
 
+       trace_dwc3_complete_trb(ep0, trb);
+
+       r = next_request(&ep0->pending_list);
+       if (!r)
+               return;
+
        status = DWC3_TRB_SIZE_TRBSTS(trb->size);
        if (status == DWC3_TRBSTS_SETUP_PENDING) {
-               dev_dbg(dwc->dev, "Setup Pending received\n");
+               dwc->setup_packet_pending = true;
+
+               dwc3_trace(trace_dwc3_ep0, "Setup Pending received");
 
                if (r)
                        dwc3_gadget_giveback(ep0, r, -ECONNRESET);
@@ -791,16 +826,38 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
                return;
        }
 
+       ur = &r->request;
+       buf = ur->buf;
+       remaining_ur_length = ur->length;
+
        length = trb->size & DWC3_TRB_SIZE_MASK;
 
+       maxp = ep0->endpoint.maxpacket;
+
        if (dwc->ep0_bounced) {
-               unsigned transfer_size = ur->length;
-               unsigned maxp = ep0->endpoint.maxpacket;
+               /*
+                * Handle the first TRB before handling the bounce buffer if
+                * the request length is greater than the bounce buffer size
+                */
+               if (ur->length > DWC3_EP0_BOUNCE_SIZE) {
+                       transfer_size = ALIGN(ur->length - maxp, maxp);
+                       transferred = transfer_size - length;
+                       buf = (u8 *)buf + transferred;
+                       ur->actual += transferred;
+                       remaining_ur_length -= transferred;
+
+                       trb++;
+                       length = trb->size & DWC3_TRB_SIZE_MASK;
+
+                       ep0->trb_enqueue = 0;
+               }
 
-               transfer_size += (maxp - (transfer_size % maxp));
-               transferred = min_t(u32, ur->length,
-                               transfer_size - length);
-               memcpy(ur->buf, dwc->ep0_bounce, transferred);
+               transfer_size = roundup((ur->length - transfer_size),
+                                       maxp);
+
+               transferred = min_t(u32, remaining_ur_length,
+                                   transfer_size - length);
+               memcpy(buf, dwc->ep0_bounce, transferred);
        } else {
                transferred = ur->length - length;
        }
@@ -812,12 +869,19 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
 
                dwc3_ep0_stall_and_restart(dwc);
        } else {
-               /*
-                * handle the case where we have to send a zero packet. This
-                * seems to be case when req.length > maxpacket. Could it be?
-                */
-               if (r)
-                       dwc3_gadget_giveback(ep0, r, 0);
+               dwc3_gadget_giveback(ep0, r, 0);
+
+               if (IS_ALIGNED(ur->length, ep0->endpoint.maxpacket) &&
+                               ur->length && ur->zero) {
+                       int ret;
+
+                       dwc->ep0_next_event = DWC3_EP0_COMPLETE;
+
+                       ret = dwc3_ep0_start_trans(dwc, epnum,
+                                       dwc->ctrl_req_addr, 0,
+                                       DWC3_TRBCTL_CONTROL_DATA, false);
+                       WARN_ON(ret < 0);
+               }
        }
 }
 
@@ -832,8 +896,10 @@ static void dwc3_ep0_complete_status(struct dwc3 *dwc,
        dep = dwc->eps[0];
        trb = dwc->ep0_trb;
 
-       if (!list_empty(&dep->request_list)) {
-               r = next_request(&dep->request_list);
+       trace_dwc3_complete_trb(dep, trb);
+
+       if (!list_empty(&dep->pending_list)) {
+               r = next_request(&dep->pending_list);
 
                dwc3_gadget_giveback(dep, r, 0);
        }
@@ -843,7 +909,7 @@ static void dwc3_ep0_complete_status(struct dwc3 *dwc,
 
                ret = dwc3_gadget_set_test_mode(dwc, dwc->test_mode_nr);
                if (ret < 0) {
-                       dev_dbg(dwc->dev, "Invalid Test #%d\n",
+                       dwc3_trace(trace_dwc3_ep0, "Invalid Test #%d",
                                        dwc->test_mode_nr);
                        dwc3_ep0_stall_and_restart(dwc);
                        return;
@@ -851,8 +917,10 @@ static void dwc3_ep0_complete_status(struct dwc3 *dwc,
        }
 
        status = DWC3_TRB_SIZE_TRBSTS(trb->size);
-       if (status == DWC3_TRBSTS_SETUP_PENDING)
-               dev_dbg(dwc->dev, "Setup Pending received\n");
+       if (status == DWC3_TRBSTS_SETUP_PENDING) {
+               dwc->setup_packet_pending = true;
+               dwc3_trace(trace_dwc3_ep0, "Setup Pending received");
+       }
 
        dwc->ep0state = EP0_SETUP_PHASE;
        dwc3_ep0_out_start(dwc);
@@ -869,17 +937,17 @@ static void dwc3_ep0_xfer_complete(struct dwc3 *dwc,
 
        switch (dwc->ep0state) {
        case EP0_SETUP_PHASE:
-               dev_vdbg(dwc->dev, "Inspecting Setup Bytes\n");
+               dwc3_trace(trace_dwc3_ep0, "Setup Phase");
                dwc3_ep0_inspect_setup(dwc, event);
                break;
 
        case EP0_DATA_PHASE:
-               dev_vdbg(dwc->dev, "Data Phase\n");
+               dwc3_trace(trace_dwc3_ep0, "Data Phase");
                dwc3_ep0_complete_data(dwc, event);
                break;
 
        case EP0_STATUS_PHASE:
-               dev_vdbg(dwc->dev, "Status Phase\n");
+               dwc3_trace(trace_dwc3_ep0, "Status Phase");
                dwc3_ep0_complete_status(dwc, event);
                break;
        default:
@@ -897,44 +965,50 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
        if (req->request.length == 0) {
                ret = dwc3_ep0_start_trans(dwc, dep->number,
                                dwc->ctrl_req_addr, 0,
-                               DWC3_TRBCTL_CONTROL_DATA);
+                               DWC3_TRBCTL_CONTROL_DATA, false);
        } else if (!IS_ALIGNED(req->request.length, dep->endpoint.maxpacket)
                        && (dep->number == 0)) {
-               u32     transfer_size;
+               u32     transfer_size = 0;
                u32     maxpacket;
 
                ret = usb_gadget_map_request(&dwc->gadget, &req->request,
                                dep->number);
                if (ret) {
-                       dev_dbg(dwc->dev, "failed to map request\n");
+                       dwc3_trace(trace_dwc3_ep0, "failed to map request");
                        return;
                }
 
-               WARN_ON(req->request.length > DWC3_EP0_BOUNCE_SIZE);
-
                maxpacket = dep->endpoint.maxpacket;
-               transfer_size = roundup(req->request.length, maxpacket);
+
+               if (req->request.length > DWC3_EP0_BOUNCE_SIZE) {
+                       transfer_size = ALIGN(req->request.length - maxpacket,
+                                             maxpacket);
+                       ret = dwc3_ep0_start_trans(dwc, dep->number,
+                                                  req->request.dma,
+                                                  transfer_size,
+                                                  DWC3_TRBCTL_CONTROL_DATA,
+                                                  true);
+               }
+
+               transfer_size = roundup((req->request.length - transfer_size),
+                                       maxpacket);
 
                dwc->ep0_bounced = true;
 
-               /*
-                * REVISIT in case request length is bigger than
-                * DWC3_EP0_BOUNCE_SIZE we will need two chained
-                * TRBs to handle the transfer.
-                */
                ret = dwc3_ep0_start_trans(dwc, dep->number,
                                dwc->ep0_bounce_addr, transfer_size,
-                               DWC3_TRBCTL_CONTROL_DATA);
+                               DWC3_TRBCTL_CONTROL_DATA, false);
        } else {
                ret = usb_gadget_map_request(&dwc->gadget, &req->request,
                                dep->number);
                if (ret) {
-                       dev_dbg(dwc->dev, "failed to map request\n");
+                       dwc3_trace(trace_dwc3_ep0, "failed to map request");
                        return;
                }
 
                ret = dwc3_ep0_start_trans(dwc, dep->number, req->request.dma,
-                               req->request.length, DWC3_TRBCTL_CONTROL_DATA);
+                               req->request.length, DWC3_TRBCTL_CONTROL_DATA,
+                               false);
        }
 
        WARN_ON(ret < 0);
@@ -949,17 +1023,11 @@ static int dwc3_ep0_start_control_status(struct dwc3_ep *dep)
                : DWC3_TRBCTL_CONTROL_STATUS2;
 
        return dwc3_ep0_start_trans(dwc, dep->number,
-                       dwc->ctrl_req_addr, 0, type);
+                       dwc->ctrl_req_addr, 0, type, false);
 }
 
 static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep *dep)
 {
-       if (dwc->resize_fifos) {
-               dev_dbg(dwc->dev, "starting to resize fifos\n");
-               dwc3_gadget_resize_tx_fifos(dwc);
-               dwc->resize_fifos = 0;
-       }
-
        WARN_ON(dwc3_ep0_start_control_status(dep));
 }
 
@@ -984,7 +1052,7 @@ static void dwc3_ep0_end_control_data(struct dwc3 *dwc, struct dwc3_ep *dep)
        cmd |= DWC3_DEPCMD_CMDIOC;
        cmd |= DWC3_DEPCMD_PARAM(dep->resource_index);
        memset(&params, 0, sizeof(params));
-       ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, cmd, &params);
+       ret = dwc3_send_gadget_ep_cmd(dep, cmd, &params);
        WARN_ON_ONCE(ret);
        dep->resource_index = 0;
 }
@@ -992,11 +1060,9 @@ static void dwc3_ep0_end_control_data(struct dwc3 *dwc, struct dwc3_ep *dep)
 static void dwc3_ep0_xfernotready(struct dwc3 *dwc,
                const struct dwc3_event_depevt *event)
 {
-       dwc->setup_packet_pending = true;
-
        switch (event->status) {
        case DEPEVT_STATUS_CONTROL_DATA:
-               dev_vdbg(dwc->dev, "Control Data\n");
+               dwc3_trace(trace_dwc3_ep0, "Control Data");
 
                /*
                 * We already have a DATA transfer in the controller's cache,
@@ -1010,7 +1076,8 @@ static void dwc3_ep0_xfernotready(struct dwc3 *dwc,
                if (dwc->ep0_expect_in != event->endpoint_number) {
                        struct dwc3_ep  *dep = dwc->eps[dwc->ep0_expect_in];
 
-                       dev_vdbg(dwc->dev, "Wrong direction for Data phase\n");
+                       dwc3_trace(trace_dwc3_ep0,
+                                       "Wrong direction for Data phase");
                        dwc3_ep0_end_control_data(dwc, dep);
                        dwc3_ep0_stall_and_restart(dwc);
                        return;
@@ -1022,13 +1089,13 @@ static void dwc3_ep0_xfernotready(struct dwc3 *dwc,
                if (dwc->ep0_next_event != DWC3_EP0_NRDY_STATUS)
                        return;
 
-               dev_vdbg(dwc->dev, "Control Status\n");
+               dwc3_trace(trace_dwc3_ep0, "Control Status");
 
                dwc->ep0state = EP0_STATUS_PHASE;
 
                if (dwc->delayed_status) {
                        WARN_ON_ONCE(event->endpoint_number != 1);
-                       dev_vdbg(dwc->dev, "Mass Storage delayed status\n");
+                       dwc3_trace(trace_dwc3_ep0, "Delayed Status");
                        return;
                }
 
@@ -1039,11 +1106,8 @@ static void dwc3_ep0_xfernotready(struct dwc3 *dwc,
 void dwc3_ep0_interrupt(struct dwc3 *dwc,
                const struct dwc3_event_depevt *event)
 {
-       u8                      epnum = event->endpoint_number;
-
-       dev_dbg(dwc->dev, "%s while ep%d%s in state '%s'\n",
-                       dwc3_ep_event_string(event->endpoint_event),
-                       epnum >> 1, (epnum & 1) ? "in" : "out",
+       dwc3_trace(trace_dwc3_ep0, "%s: state '%s'",
+                       dwc3_ep_event_string(event),
                        dwc3_ep0_state_string(dwc->ep0state));
 
        switch (event->endpoint_event) {