Re: [PATCH] usb: dwc3: issue Update Transfer command after queuing isoc request

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

 



Hi,

On Thu, Mar 29, 2012 at 06:16:54PM +0000, Paul Zimmerman wrote:
> Issue an Update Transfer command after queuing a request to an isoc
> EP with an active transfer. This is required according to the dwc3
> databook. Pratyush Anand reports that this fixes a problem he was
> having with Isoc IN transfers.
> 
> Signed-off-by: Paul Zimmerman <paulz@xxxxxxxxxxxx>

Still waiting for a tested-by here...

> ---
>  Pratyush, this is a cleaned-up version of the original patch, which
>  also updates the comment in __dwc3_gadget_ep_queue() to describe
>  this case. If you could, please test this version and give your
>  tested-by if it works OK.
> 
>  drivers/usb/dwc3/gadget.c |   45 ++++++++++++++++++++++++++++-----------------
>  1 files changed, 28 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
> index 5255fe9..cee4e45 100644
> --- a/drivers/usb/dwc3/gadget.c
> +++ b/drivers/usb/dwc3/gadget.c
> @@ -930,10 +930,12 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep, u16 cmd_param,
>  	}
>  
>  	dep->flags |= DWC3_EP_BUSY;
> -	dep->res_trans_idx = dwc3_gadget_ep_get_transfer_index(dwc,
> -			dep->number);
>  
> -	WARN_ON_ONCE(!dep->res_trans_idx);
> +	if (start_new) {
> +		dep->res_trans_idx = dwc3_gadget_ep_get_transfer_index(dwc,
> +				dep->number);
> +		WARN_ON_ONCE(!dep->res_trans_idx);
> +	}
>  
>  	return 0;
>  }
> @@ -967,28 +969,37 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
>  
>  	list_add_tail(&req->list, &dep->request_list);
>  
> +	if (usb_endpoint_xfer_isoc(dep->desc) && (dep->flags & DWC3_EP_BUSY))
> +		dep->flags |= DWC3_EP_PENDING_REQUEST;
> +
>  	/*
> -	 * There is one special case: XferNotReady with
> -	 * empty list of requests. We need to kick the
> -	 * transfer here in that situation, otherwise
> -	 * we will be NAKing forever.
> +	 * There are two special cases:
>  	 *
> -	 * If we get XferNotReady before gadget driver
> -	 * has a chance to queue a request, we will ACK
> -	 * the IRQ but won't be able to receive the data
> -	 * until the next request is queued. The following
> -	 * code is handling exactly that.
> +	 * 1. XferNotReady with empty list of requests. We need to kick the
> +	 *    transfer here in that situation, otherwise we will be NAKing
> +	 *    forever. If we get XferNotReady before gadget driver has a
> +	 *    chance to queue a request, we will ACK the IRQ but won't be
> +	 *    able to receive the data until the next request is queued.
> +	 *    The following code is handling exactly that.
> +	 *
> +	 * 2. XferInProgress on Isoc EP with an active transfer. We need to
> +	 *    kick the transfer here after queuing a request, otherwise the
> +	 *    core may not see the modified TRB(s).
>  	 */
>  	if (dep->flags & DWC3_EP_PENDING_REQUEST) {
> -		int ret;
> -		int start_trans;
> +		int	ret;
> +		int	start_trans = 1;
> +		u8	trans_idx = dep->res_trans_idx;
>  
> -		start_trans = 1;
>  		if (usb_endpoint_xfer_isoc(dep->desc) &&
> -				(dep->flags & DWC3_EP_BUSY))
> +				(dep->flags & DWC3_EP_BUSY)) {
>  			start_trans = 0;
> +			WARN_ON_ONCE(!trans_idx);
> +		} else {
> +			trans_idx = 0;
> +		}
>  
> -		ret = __dwc3_gadget_kick_transfer(dep, 0, start_trans);
> +		ret = __dwc3_gadget_kick_transfer(dep, trans_idx, start_trans);
>  		if (ret && ret != -EBUSY) {
>  			struct dwc3	*dwc = dep->dwc;
>  
> -- 
> Paul
> 

-- 
balbi

Attachment: signature.asc
Description: Digital signature


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

  Powered by Linux