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); ? -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | -- 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