Re: [PATCH v2 4/6] usb: dwc3: gadget: add remaining sg entries to ring

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

 



Hi Felipe,

On 8/15/2016 4:02 AM, Felipe Balbi wrote:
> Upon transfer completion after a full ring, let's
> add more TRBs to our ring in order to complete our
> request successfully.
> 
> Signed-off-by: Felipe Balbi <felipe.balbi@xxxxxxxxxxxxxxx>
> ---
>  drivers/usb/dwc3/gadget.c | 36 ++++++++++++++++++++++++------------
>  1 file changed, 24 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
> index 90b3d7965136..6483991c8013 100644
> --- a/drivers/usb/dwc3/gadget.c
> +++ b/drivers/usb/dwc3/gadget.c
> @@ -888,14 +888,13 @@ static u32 dwc3_calc_trbs_left(struct dwc3_ep *dep)
>  static void dwc3_prepare_one_trb_sg(struct dwc3_ep *dep,
>  		struct dwc3_request *req, unsigned int trbs_left)
>  {
> -	struct usb_request *request = &req->request;
> -	struct scatterlist *sg = request->sg;
> +	struct scatterlist *sg = req->sg;
>  	struct scatterlist *s;
>  	unsigned int	length;
>  	dma_addr_t	dma;
>  	int		i;
>  
> -	for_each_sg(sg, s, request->num_mapped_sgs, i) {
> +	for_each_sg(sg, s, req->num_pending_sgs, i) {
>  		unsigned chain = true;
>  
>  		length = sg_dma_len(s);
> @@ -945,7 +944,7 @@ static void dwc3_prepare_trbs(struct dwc3_ep *dep)
>  		return;
>  
>  	list_for_each_entry_safe(req, n, &dep->pending_list, list) {
> -		if (req->request.num_mapped_sgs > 0)
> +		if (req->num_pending_sgs > 0)
>  			dwc3_prepare_one_trb_sg(dep, req, trbs_left--);
>  		else
>  			dwc3_prepare_one_trb_linear(dep, req, trbs_left--);
> @@ -1071,6 +1070,9 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
>  	if (ret)
>  		return ret;
>  
> +	req->sg			= req->request.sg;
> +	req->num_pending_sgs	= req->request.num_mapped_sgs;
> +
>  	list_add_tail(&req->list, &dep->pending_list);
>  
>  	if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
> @@ -1935,22 +1937,30 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep,
>  	int			ret;
>  
>  	list_for_each_entry_safe(req, n, &dep->started_list, list) {
> -
> +		unsigned length;
> +		unsigned actual;
>  		int chain;
>  
> -		chain = req->request.num_mapped_sgs > 0;
> +		length = req->request.length;
> +		chain = req->num_pending_sgs > 0;
>  		if (chain) {
> -			struct scatterlist *sg = req->request.sg;
> +			struct scatterlist *sg = req->sg;
>  			struct scatterlist *s;
> +			unsigned int pending = req->num_pending_sgs;
>  			unsigned int i;
>  
> -			for_each_sg(sg, s, req->request.num_mapped_sgs, i) {
> +			for_each_sg(sg, s, pending, i) {
>  				trb = &dep->trb_pool[dep->trb_dequeue];
>  				count += trb->size & DWC3_TRB_SIZE_MASK;
>  				dwc3_ep_inc_deq(dep);
>  
> +				req->sg = sg_next(s);
> +				req->num_pending_sgs--;
> +
>  				ret = __dwc3_cleanup_done_trbs(dwc, dep, req, trb,
>  						event, status, chain);
> +				if (ret)
> +					break;
>  			}
>  		} else {
>  			trb = &dep->trb_pool[dep->trb_dequeue];
> @@ -1968,11 +1978,13 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep,
>  		 * should receive and we simply bounce the request back to the
>  		 * gadget driver for further processing.
>  		 */
> -		req->request.actual += req->request.length - count;
> -		dwc3_gadget_giveback(dep, req, status);
> +		actual = length - req->request.actual;
> +		req->request.actual = actual;
>  
> -		if (ret)
> -			break;
> +		if (ret && chain && (actual < length) && req->num_pending_sgs)
> +			return __dwc3_gadget_kick_transfer(dep, 0);
> +
> +		dwc3_gadget_giveback(dep, req, status);
>  	}
>  
>  	/*
> 

On your testing/next, I see considerable slow down and file
corruption in mass storage.

After bisecting, this patch seems to be the first one that shows
problems. The device fails even enumeration here.

I haven't looked in detail at the changes but, do you have any ideas?

I have attached driver logs.

Regards,
John

Attachment: log.tar.gz
Description: application/gzip


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

  Powered by Linux