summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelipe Balbi <felipe.balbi@linux.intel.com>2016-12-20 12:57:32 +0100
committerFelipe Balbi <felipe.balbi@linux.intel.com>2017-01-02 09:55:28 +0100
commit7931ec86c1b738e4e90e58c6d95e5f720d45ee56 (patch)
tree7927404f8e034dcc90dabcff1f192e2754ffe05a
parentusb: dwc2: gadget: fix default value for gadget-dma-desc (diff)
downloadlinux-7931ec86c1b738e4e90e58c6d95e5f720d45ee56.tar.xz
linux-7931ec86c1b738e4e90e58c6d95e5f720d45ee56.zip
usb: dwc3: ep0: add dwc3_ep0_prepare_one_trb()
For now this is just a cleanup patch, no functional changes. We will be using the new function to fix a bug introduced long ago by commit 0416e494ce7d ("usb: dwc3: ep0: correct cache sync issue in case of ep0_bounced") and further worsened by commit c0bd5456a470 ("usb: dwc3: ep0: handle non maxpacket aligned transfers > 512") Cc: <stable@vger.kernel.org> Reported-by: Janusz Dziedzic <januszx.dziedzic@linux.intel.com> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
-rw-r--r--drivers/usb/dwc3/ep0.c26
1 files changed, 16 insertions, 10 deletions
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index 4878d187c7d4..06febd07ec4e 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -39,18 +39,13 @@ static void __dwc3_ep0_do_control_status(struct dwc3 *dwc, struct dwc3_ep *dep);
static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
struct dwc3_ep *dep, struct dwc3_request *req);
-static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma,
- u32 len, u32 type, bool chain)
+static void dwc3_ep0_prepare_one_trb(struct dwc3 *dwc, u8 epnum,
+ dma_addr_t buf_dma, u32 len, u32 type, bool chain)
{
- struct dwc3_gadget_ep_cmd_params params;
struct dwc3_trb *trb;
struct dwc3_ep *dep;
- int ret;
-
dep = dwc->eps[epnum];
- if (dep->flags & DWC3_EP_BUSY)
- return 0;
trb = &dwc->ep0_trb[dep->trb_enqueue];
@@ -71,15 +66,26 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma,
trb->ctrl |= (DWC3_TRB_CTRL_IOC
| DWC3_TRB_CTRL_LST);
- if (chain)
+ trace_dwc3_prepare_trb(dep, trb);
+}
+
+static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma,
+ u32 len, u32 type, bool chain)
+{
+ struct dwc3_gadget_ep_cmd_params params;
+ struct dwc3_ep *dep;
+ int ret;
+
+ dep = dwc->eps[epnum];
+ if (dep->flags & DWC3_EP_BUSY)
return 0;
+ dwc3_ep0_prepare_one_trb(dwc, epnum, buf_dma, len, type, chain);
+
memset(&params, 0, sizeof(params));
params.param0 = upper_32_bits(dwc->ep0_trb_addr);
params.param1 = lower_32_bits(dwc->ep0_trb_addr);
- trace_dwc3_prepare_trb(dep, trb);
-
ret = dwc3_send_gadget_ep_cmd(dep, DWC3_DEPCMD_STARTTRANSFER, &params);
if (ret < 0)
return ret;