Skip to content

Commit

Permalink
usb: dwc3: gadget: fix isoc END TRANSFER Condition
Browse files Browse the repository at this point in the history
There were still some corner cases where isoc transfer was not able to
restart, specially when missed isoc does not happen , and in fact gadget does
not queue any new request during giveback.

Cleanup function calls giveback first, which provides a way to queue
another request to gadget. But gadget did not had any data. So , it did
not call ep_queue. To twist it further, gadget did not queue till
cleanup for last queued TRB is called. If we ever reach this scenario,
we must call END TRANSFER, so that we receive a new  xfernotready with
information about current microframe number.

Also insure that there is no request submitted to core when issuing END
TRANSFER.

Cc: <[email protected]> # v3.8
Signed-off-by: Pratyush Anand <[email protected]>
Signed-off-by: Felipe Balbi <[email protected]>
  • Loading branch information
Pratyush Anand authored and Felipe Balbi committed Jan 18, 2013
1 parent 15f86bd commit cdc359d
Showing 1 changed file with 18 additions and 5 deletions.
23 changes: 18 additions & 5 deletions drivers/usb/dwc3/gadget.c
Original file line number Diff line number Diff line change
Expand Up @@ -1089,7 +1089,10 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
* notion of current microframe.
*/
if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
dwc3_stop_active_transfer(dwc, dep->number);
if (list_empty(&dep->req_queued)) {
dwc3_stop_active_transfer(dwc, dep->number);
dep->flags = DWC3_EP_ENABLED;
}
return 0;
}

Expand Down Expand Up @@ -1727,10 +1730,20 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep,
break;
} while (1);

if (list_empty(&dep->req_queued) &&
(dep->flags & DWC3_EP_MISSED_ISOC)) {
dwc3_stop_active_transfer(dwc, dep->number);
dep->flags &= ~DWC3_EP_MISSED_ISOC;
if (usb_endpoint_xfer_isoc(dep->endpoint.desc) &&
list_empty(&dep->req_queued)) {
if (list_empty(&dep->request_list)) {
/*
* If there is no entry in request list then do
* not issue END TRANSFER now. Just set PENDING
* flag, so that END TRANSFER is issued when an
* entry is added into request list.
*/
dep->flags = DWC3_EP_PENDING_REQUEST;
} else {
dwc3_stop_active_transfer(dwc, dep->number);
dep->flags = DWC3_EP_ENABLED;
}
return 1;
}

Expand Down

0 comments on commit cdc359d

Please sign in to comment.