When test usb gadget uvc function, we find a isoc in
ep transfer bug that will cause uvc data transfer fail.
The error case is:
1. The current EP request is done, call complete_ep()
to completes the request, and then call start_next_request()
to check the EP request queue, in this error case, the
queue is empty, so it doesn't start next request, just
set ep frame_num to 0xFFFFFFFF.
2. NAK Interrutp is triggered, check isoc ep frame_num
is 0xFFFFFFFF, then reset the frame_num to 0, and then
call start_next_request() to check the EP request queue,
in this error case, the queue is still empty, so set ep
frame_num to 0xFFFFFFFF again.
But afer the above operation, the current code will
modify the ep frame_num in NAK Interrutp handler by
add ep bInterval to frame_num, this cause frame_num
change again, but not keep in 0xFFFFFFFF, so the next
NAK Interrutp handler doesn't start next request any
more.
This patch reset the frame_num to the current frame
number got from DSTS SOFFN register if detect the
frame_num is 0xFFFFFFFF in NAK Interrutp handler.
And modify the frame_num in NAK Interrutp handler
only when the frame_num is not 0xFFFFFFFF.
TEST=Set usb gadget as webcam, use Ubuntu Guvcview
to preview the webcam, observe the preview screen
and the error log "There are no more ISOC requests".
Change-Id: I4403a67b1d5d257d092a2a71d5666c5d6fd5af3c
Signed-off-by: William Wu <wulf@rock-chips.com>
depctl_data_t depctl;
if (ep->dwc_ep.frame_num == 0xFFFFFFFF) {
ep->dwc_ep.frame_num =
- core_if->frame_num;
+ dwc_otg_get_frame_number(core_if);
if (ep->dwc_ep.bInterval > 1) {
depctl.d32 = 0;
depctl.d32 =
}
start_next_request(ep);
}
- ep->dwc_ep.frame_num +=
- ep->dwc_ep.bInterval;
- if (dwc_ep->frame_num > 0x3FFF) {
- dwc_ep->frm_overrun = 1;
- dwc_ep->frame_num &= 0x3FFF;
- } else
- dwc_ep->frm_overrun = 0;
+
+ if (ep->dwc_ep.frame_num !=
+ 0xFFFFFFFF) {
+ ep->dwc_ep.frame_num +=
+ ep->dwc_ep.bInterval;
+ if (dwc_ep->frame_num >
+ 0x3FFF) {
+ dwc_ep->frm_overrun = 1;
+ dwc_ep->frame_num &=
+ 0x3FFF;
+ } else {
+ dwc_ep->frm_overrun = 0;
+ }
+ }
}
CLEAR_IN_EP_INTR(core_if, epnum, nak);