[PATCH v3] usb: dwc2: Fix control OUT transfer issue

Chance.Yang chance.yang at vatics.com
Tue Oct 6 04:55:49 CEST 2020


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 at vatics.com>
---

Changes for v2:
   - fixed 'cast from pointer to integer of different size'
Changes for v3:
   - fixed the typo on subject
   - remove the unnecessary extra braces
---
 drivers/usb/gadget/dwc2_udc_otg_xfer_dma.c | 16 +++++++++++++---
 1 file 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 1c0505eb28..f17009a29e 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();
 					}
-- 
2.17.1



More information about the U-Boot mailing list