Re: [PATCH 6/6] usb: dwc3: gadget: Delay issuing End Transfer

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Apr 21, 2022 at 07:23:03PM -0700, Thinh Nguyen wrote:
> If the controller hasn't DMA'ed the Setup data from its fifo, it won't
> process the End Transfer command. Polling for the command completion may
> block the driver from servicing the Setup phase and cause a timeout.
> Previously we only check and delay issuing End Transfer in the case of
> endpoint dequeue. Let's do that for all End Transfer scenarios.
> 
> Signed-off-by: Thinh Nguyen <Thinh.Nguyen@xxxxxxxxxxxx>
> ---
>  drivers/usb/dwc3/gadget.c | 22 ++++++++++++----------
>  1 file changed, 12 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
> index 7c4d5f671687..f0fd7c32828b 100644
> --- a/drivers/usb/dwc3/gadget.c
> +++ b/drivers/usb/dwc3/gadget.c
> @@ -2056,16 +2056,6 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
>  		if (r == req) {
>  			struct dwc3_request *t;
>  
> -			/*
> -			 * If a Setup packet is received but yet to DMA out, the controller will
> -			 * not process the End Transfer command of any endpoint. Polling of its
> -			 * DEPCMD.CmdAct may block setting up TRB for Setup packet, causing a
> -			 * timeout. Delay issuing the End Transfer command until the Setup TRB is
> -			 * prepared.
> -			 */
> -			if (dwc->ep0state != EP0_SETUP_PHASE && !dwc->delayed_status)
> -				dep->flags |= DWC3_EP_DELAY_STOP;
> -
>  			/* wait until it is processed */
>  			dwc3_stop_active_transfer(dep, true, true);
>  
> @@ -3657,6 +3647,18 @@ void dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force,
>  	    (dep->flags & DWC3_EP_END_TRANSFER_PENDING))
>  		return;
>  
> +	/*
> +	 * If a Setup packet is received but yet to DMA out, the controller will
> +	 * not process the End Transfer command of any endpoint. Polling of its
> +	 * DEPCMD.CmdAct may block setting up TRB for Setup packet, causing a
> +	 * timeout. Delay issuing the End Transfer command until the Setup TRB is
> +	 * prepared.
> +	 */
> +	if (dwc->ep0state != EP0_SETUP_PHASE && !dwc->delayed_status) {
> +		dep->flags |= DWC3_EP_DELAY_STOP;
> +		return;
> +	}
> +

dwc3_remove_requests() calls dwc3_stop_active_transfer() but does not check
any flags before retiring all the requests. should we add some assert/WARN_ON
to make sure that we are not retiring the requests before stopping the active
transfers?

Thanks,
Pavan



[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux