Re: [PATCH v2 2/2] USB: gadget: update ci13xxx to work with g_ether

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

 



On 12/13/2010 1:36 PM, Artem Leonenko wrote:
> There is one nasty scenario when CI13xxx driver fails:
>        a) two or more rx requests are queued (g_ether does that)
>        b) rx request completed, interrupt fires and ci13xxx dequeues rq
>        c) request complete() callback gets called and in turn it calls
> ep_queue()
>                c1) in ep_queue() request gets added to the TAIL of the
> rx queue list
>        d) ep gets primed with rq from (b)
>        e) interrupt fires
>        f) request gets popped from queue head for hw dequeue
>        G) requets from queue head wasn't enqueued
>                g1)  isr_tr_complete_low() doesn't
>                enqueue more requests and it doesn't prime EP,
>                rx traffic stalls
> 
> Solution:
>        a) enque queued requests ASAP, i.e. before calling complete()
> callback.
>        b) don't HW enqueue and prime endpoint with recently added
> request and
>        use the oldest request in the queue.
> 
> Fixed issues:
>        a) ep_queue() may return an error code despite request was
> successfully
>        added to the queue (if _hardware_enqueue() fails)
>        b) Added requests are always processed in LIFO order, even if
> they are
>        added in complete() callback
>        c) Finally more than two and more queued requests are processed
> consistently,
>        even if they were added in complete() callback
> 
> The fix was successfully tested on MIPS based SoC with 4KEc CPU core and
> CI13612 USB core. Board successfully boots with NFS root using g_ether
> on ci13xxx udc.
> 
> Signed-off-by: Artem Leonenko <tikkeri@xxxxxxxxx>
> ---
>  drivers/usb/gadget/ci13xxx_udc.c |   14 ++++++++------
>  1 files changed, 8 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/usb/gadget/ci13xxx_udc.c
> b/drivers/usb/gadget/ci13xxx_udc.c
> index 03505cb..0164a81 100644
> --- a/drivers/usb/gadget/ci13xxx_udc.c
> +++ b/drivers/usb/gadget/ci13xxx_udc.c
> @@ -1794,18 +1794,20 @@ __acquires(mEp->lock)
> 
>  	dbg_done(_usb_addr(mEp), mReq->ptr->token, retval);
> 
> +	if (!list_empty(&mEp->qh[mEp->dir].queue)) {
> +		struct ci13xxx_req* mReqEnq;
> +
> +		mReqEnq = list_entry(mEp->qh[mEp->dir].queue.next,
> +				  struct ci13xxx_req, queue);
> +		_hardware_enqueue(mEp, mReqEnq);
> +	}
> +
>  	if (!mReq->req.no_interrupt && mReq->req.complete != NULL) {
>  		spin_unlock(mEp->lock);
>  		mReq->req.complete(&mEp->ep, &mReq->req);
>  		spin_lock(mEp->lock);
>  	}
> 
> -	if (!list_empty(&mEp->qh[mEp->dir].queue)) {
> -		mReq = list_entry(mEp->qh[mEp->dir].queue.next,
> -				  struct ci13xxx_req, queue);
> -		_hardware_enqueue(mEp, mReq);
> -	}
> -
>   done:
>  	return retval;
>  }

You did not add the fix to check the list status before calling
_hardware_enqueue in ep_queue function in this patch set.


-- 
Sent by a consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


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

  Powered by Linux