Re: [PATCH 1/1] usb: chipidea: udc: delete td from req's td list at ep_dequeue

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

 



On Mon, Jun 30, 2014 at 02:19:04PM +0200, Michael Grzeschik wrote:
> On Mon, Jun 30, 2014 at 12:15:03PM +0800, Peter Chen wrote:
> > We need to delete un-finished td from current request's td list
> > at ep_dequeue API, otherwise, this non-user td will be remained
> > at td list before this request is freed. So if we do ep_queue->
> > ep_dequeue->ep_queue sequence, when the complete interrupt for
> > the second ep_queue comes, we search td list for this request,
> > the first td (added by the first ep_queue) will be handled, and
> > its status is still active, so we will consider the this transfer
> > still not be completed, but in fact, it has completed. It causes
> > the peripheral side considers it never receives current data for
> > this transfer.
> > 
> > We met this problem when do "Error Recovery Test - Device Configured"
> > test item for USBCV2 MSC test, the host has never received ACK for
> > the IN token for CSW due to peripheral considers it does not get this
> > CBW, the USBCV test log like belows:
> > 
> > --------------------------------------------------------------------------
> > INFO
> > Issuing BOT MSC Reset, reset should always succeed
> > INFO
> > Retrieving status on CBW endpoint
> > INFO
> > CBW endpoint status = 0x0
> > INFO
> > Retrieving status on CSW endpoint
> > INFO
> > CSW endpoint status = 0x0
> > INFO
> > Issuing required command (Test Unit Ready) to verify device has recovered
> > INFO
> > Issuing CBW (attempt #1):
> > INFO
> > |----- CBW LUN                  = 0x0
> > INFO
> > |----- CBW Flags                = 0x0
> > INFO
> > |----- CBW Data Transfer Length = 0x0
> > INFO
> > |----- CBW CDB Length           = 0x6
> > INFO
> > |----- CBW CDB-00 = 0x0
> > INFO
> > |----- CBW CDB-01 = 0x0
> > INFO
> > |----- CBW CDB-02 = 0x0
> > INFO
> > |----- CBW CDB-03 = 0x0
> > INFO
> > |----- CBW CDB-04 = 0x0
> > INFO
> > |----- CBW CDB-05 = 0x0
> > INFO
> > Issuing CSW : try 1
> > INFO
> > CSW Bulk Request timed out!
> > ERROR
> > Failed CSW phase : should have been success or stall
> > FAIL
> > (5.3.4) The CSW status value must be 0x00, 0x01, or 0x02.
> > ERROR
> > BOTCommonMSCRequest failed:  error=80004000
> > 
> > Cc: stable@xxxxxxxxxxxxxxx
> > Signed-off-by: Peter Chen <peter.chen@xxxxxxxxxxxxx>
> > ---
> >  drivers/usb/chipidea/udc.c |    8 ++++++++
> >  1 files changed, 8 insertions(+), 0 deletions(-)
> > 
> > diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
> > index 69425b3..0522e59 100644
> > --- a/drivers/usb/chipidea/udc.c
> > +++ b/drivers/usb/chipidea/udc.c
> > @@ -1321,6 +1321,7 @@ static int ep_dequeue(struct usb_ep *ep, struct usb_request *req)
> >  	struct ci_hw_ep  *hwep  = container_of(ep,  struct ci_hw_ep, ep);
> >  	struct ci_hw_req *hwreq = container_of(req, struct ci_hw_req, req);
> >  	unsigned long flags;
> > +	struct td_node *node, *tmpnode;
> >  
> >  	if (ep == NULL || req == NULL || hwreq->req.status != -EALREADY ||
> >  		hwep->ep.desc == NULL || list_empty(&hwreq->queue) ||
> > @@ -1331,6 +1332,13 @@ static int ep_dequeue(struct usb_ep *ep, struct usb_request *req)
> >  
> >  	hw_ep_flush(hwep->ci, hwep->num, hwep->dir);
> >  
> > +	list_for_each_entry_safe(node, tmpnode, &hwreq->tds, td) {
> > +		dma_pool_free(hwep->td_pool, node->ptr, node->dma);
> > +		list_del_init(&node->td);
> > +		node->ptr = NULL;
> > +		kfree(node);
> > +	}
> > +
> 
> Can't we reuse ep_free_request after the list_del_init(&hwreq->queue); ?
> 

No, we can't, we may still use this request later, we can't free it.

-- 

Best Regards,
Peter Chen
--
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