mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 20:07:46 +09:00
usb: dwc_otg_310: pcd: fix isoc in ep transfer issue
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>
This commit is contained in:
@@ -4182,7 +4182,7 @@ do { \
|
||||
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 =
|
||||
@@ -4213,13 +4213,20 @@ do { \
|
||||
}
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user