[PATCH] usb: dwc2: Fix contorl 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 ---
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..9ff9cd5694 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 = (u32)®->out_endp[ep_num].doeptsiz; + u32 req_size = sizeof(struct usb_ctrlrequest);
ep_intr = readl(®->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(); }

On 9/22/20 10:48 AM, Chance.Yang wrote:
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.
Applied to usb/next, thanks
participants (2)
-
Chance.Yang
-
Marek Vasut