aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
authorChance.Yang <chance.yang@vatics.com>2020-10-06 10:55:49 +0800
committerMarek Vasut <marex@denx.de>2020-10-20 00:48:58 +0200
commit30656802355313a87d832f282d4112b403ed7131 (patch)
treeb6300459af9d6b7f555f02e5a8c1fbbb6cad83b3 /drivers/usb
parent3fade88686e71c9acee4cbeb3ae9706bbc845608 (diff)
downloadu-boot-30656802355313a87d832f282d4112b403ed7131.zip
u-boot-30656802355313a87d832f282d4112b403ed7131.tar.gz
u-boot-30656802355313a87d832f282d4112b403ed7131.tar.bz2
usb: dwc2: Fix control OUT transfer issue
In buffer DMA mode, gadget should re-configure EP 0 to received SETUP packets when doeptsiz.xfersize is equal to a setup packet size(8 bytes) and EP 0 is in WAIT_FOR_SETUP state. Since EP 0 is not enabled in WAIT_FOR_SETUP state, SETUP packets is NOT received from RxFifo and wriiten to the external memory. Signed-off-by: Chance.Yang <chance.yang@vatics.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/gadget/dwc2_udc_otg_xfer_dma.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/drivers/usb/gadget/dwc2_udc_otg_xfer_dma.c b/drivers/usb/gadget/dwc2_udc_otg_xfer_dma.c
index 1c0505e..f17009a 100644
--- a/drivers/usb/gadget/dwc2_udc_otg_xfer_dma.c
+++ b/drivers/usb/gadget/dwc2_udc_otg_xfer_dma.c
@@ -421,6 +421,9 @@ static void process_ep_out_intr(struct dwc2_udc *dev)
{
u32 ep_intr, ep_intr_status;
u8 ep_num = 0;
+ u32 ep_tsr = 0, xfer_size = 0;
+ u32 epsiz_reg = reg->out_endp[ep_num].doeptsiz;
+ u32 req_size = sizeof(struct usb_ctrlrequest);
ep_intr = readl(&reg->daint);
debug_cond(DEBUG_OUT_EP != 0,
@@ -441,10 +444,17 @@ static void process_ep_out_intr(struct dwc2_udc *dev)
if (ep_num == 0) {
if (ep_intr_status & TRANSFER_DONE) {
- if (dev->ep0state !=
- WAIT_FOR_OUT_COMPLETE)
+ ep_tsr = readl(&epsiz_reg);
+ xfer_size = ep_tsr &
+ DOEPT_SIZ_XFER_SIZE_MAX_EP0;
+
+ if (xfer_size == req_size &&
+ dev->ep0state == WAIT_FOR_SETUP) {
+ dwc2_udc_pre_setup();
+ } else if (dev->ep0state !=
+ WAIT_FOR_OUT_COMPLETE) {
complete_rx(dev, ep_num);
- else {
+ } else {
dev->ep0state = WAIT_FOR_SETUP;
dwc2_udc_pre_setup();
}