aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Chen <peter.chen@freescale.com>2014-05-28 20:11:14 -0400
committerPeter Chen <peter.chen@freescale.com>2014-06-26 00:26:27 -0400
commitca252c87f19cf1cabb6532ceb3dbe970ad5eb6d6 (patch)
tree6a8136191a1cc4c260974449d8814f3b5a3f5256
parent4ea89269fcfffd9d8374f9ed8fa57996a561c5f7 (diff)
usb: chipidea: udc: delete td from req's td list at ep_dequeue
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 Signed-off-by: Peter Chen <peter.chen@freescale.com> Signed-off-by: Shawn Guo <shawn.guo@linaro.org> (cherry picked from commit b2a4b1a887548906c4d28a86ce3a1c7bcfb8406f)
-rw-r--r--drivers/usb/chipidea/udc.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
index a32c18cffd62..d1caed19ba59 100644
--- a/drivers/usb/chipidea/udc.c
+++ b/drivers/usb/chipidea/udc.c
@@ -1323,6 +1323,7 @@ static int ep_dequeue(struct usb_ep *ep, struct usb_request *req)
1323 struct ci_hw_ep *hwep = container_of(ep, struct ci_hw_ep, ep); 1323 struct ci_hw_ep *hwep = container_of(ep, struct ci_hw_ep, ep);
1324 struct ci_hw_req *hwreq = container_of(req, struct ci_hw_req, req); 1324 struct ci_hw_req *hwreq = container_of(req, struct ci_hw_req, req);
1325 unsigned long flags; 1325 unsigned long flags;
1326 struct td_node *node, *tmpnode;
1326 1327
1327 if (ep == NULL || req == NULL || hwreq->req.status != -EALREADY || 1328 if (ep == NULL || req == NULL || hwreq->req.status != -EALREADY ||
1328 hwep->ep.desc == NULL || list_empty(&hwreq->queue) || 1329 hwep->ep.desc == NULL || list_empty(&hwreq->queue) ||
@@ -1333,6 +1334,13 @@ static int ep_dequeue(struct usb_ep *ep, struct usb_request *req)
1333 if (hwep->ci->gadget.speed != USB_SPEED_UNKNOWN) 1334 if (hwep->ci->gadget.speed != USB_SPEED_UNKNOWN)
1334 hw_ep_flush(hwep->ci, hwep->num, hwep->dir); 1335 hw_ep_flush(hwep->ci, hwep->num, hwep->dir);
1335 1336
1337 list_for_each_entry_safe(node, tmpnode, &hwreq->tds, td) {
1338 dma_pool_free(hwep->td_pool, node->ptr, node->dma);
1339 list_del_init(&node->td);
1340 node->ptr = NULL;
1341 kfree(node);
1342 }
1343
1336 /* pop request */ 1344 /* pop request */
1337 list_del_init(&hwreq->queue); 1345 list_del_init(&hwreq->queue);
1338 1346