dwc3 can do only max packet aligned transfers. So in case request
length is not max packet aligned and is bigger than
DWC3_EP0_BOUNCE_SIZE two chained TRBs is required to handle the
transfer.
Signed-off-by: Kishon Vijay Abraham I <kis...@ti.com>
---
drivers/usb/dwc3/ep0.c | 72
+++++++++++++++++++++++++++++++++------------
drivers/usb/dwc3/gadget.c | 2 +- 2 files changed, 55
insertions(+), 19 deletions(-)
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index fce2558..c2fe0ec 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -48,7 +48,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, unsigned chain)
{
struct dwc3_gadget_ep_cmd_params params;
struct dwc3_trb *trb;
@@ -62,7 +62,10 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc,
u8 epnum, dma_addr_t buf_dma, return 0;
}
- trb = dwc->ep0_trb;
+ trb = &dwc->ep0_trb[dep->free_slot];
+
+ if (chain)
+ dep->free_slot++;
trb->bpl = lower_32_bits(buf_dma);
trb->bph = upper_32_bits(buf_dma);
@@ -70,13 +73,20 @@ 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);
+
dwc3_flush_cache((int)buf_dma, len);
dwc3_flush_cache((int)trb, sizeof(*trb));
+ if (chain)
+ return 0;
+
memset(¶ms, 0, sizeof(params));
params.param0 = upper_32_bits(dwc->ep0_trb_addr);
params.param1 = lower_32_bits(dwc->ep0_trb_addr);
@@ -289,7 +299,7 @@ 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, 0);
WARN_ON(ret < 0);
}
@@ -799,6 +809,23 @@ static void dwc3_ep0_complete_data(struct dwc3
*dwc,
maxp = ep0->endpoint.maxpacket;
+ /* Handle the first TRB before handling the bounce buffer if
the request