Hi Felipe, On 8/20/2018 3:34 AM, Felipe Balbi wrote: > Gadget driver may take an unbounded amount of time to queue requests > after XferNotReady. This is important for isochronous endpoints which > need to be started for a specific (micro-)frame. > > Before kicking the transfer, let's check if current frame number is > still less than our aligned frame number that we got from the > previous XferNotReady. If it isn't, then we'll increment > dep->frame_number to make sure it's ahead of current frame number. > > Signed-off-by: Felipe Balbi <felipe.balbi@xxxxxxxxxxxxxxx> > --- > drivers/usb/dwc3/core.h | 2 ++ > drivers/usb/dwc3/gadget.c | 11 +++++++++++ > 2 files changed, 13 insertions(+) > > diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h > index 285ce0ef3b91..3acf8788a680 100644 > --- a/drivers/usb/dwc3/core.h > +++ b/drivers/usb/dwc3/core.h > @@ -685,6 +685,8 @@ struct dwc3_ep { > u8 type; > u8 resource_index; > u32 frame_number; > +#define DWC3_EP_FRAME_NUMBER_MASK 0x3fff > + > u32 interval; > > char name[20]; > diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c > index f61a4250c883..0bac9b02f28b 100644 > --- a/drivers/usb/dwc3/gadget.c > +++ b/drivers/usb/dwc3/gadget.c > @@ -1257,6 +1257,9 @@ static int __dwc3_gadget_get_frame(struct dwc3 *dwc) > > static int __dwc3_gadget_start_isoc(struct dwc3_ep *dep) > { > + u16 current_frame_number; > + u16 frame_number; > + > if (list_empty(&dep->pending_list)) { > dev_info(dep->dwc->dev, "%s: ran out of requests\n", > dep->name); > @@ -1265,6 +1268,14 @@ static int __dwc3_gadget_start_isoc(struct dwc3_ep *dep) > } > > dep->frame_number = DWC3_ALIGN_FRAME(dep); > + current_frame_number = __dwc3_gadget_get_frame(dep->dwc); > + frame_number = dep->frame_number & DWC3_EP_FRAME_NUMBER_MASK; > + > + if (frame_number <= current_frame_number) { This is not right. You're comparing (what should be a 16-bit but masked) frame_number to a 14-bit current_frame_number. If the current frame number is 2+ seconds ahead of dep->frame_number, then this calculation is wrong. > + dep->frame_number += current_frame_number - frame_number; > + dep->frame_number = DWC3_ALIGN_FRAME(dep); > + } > + > return __dwc3_gadget_kick_transfer(dep); > } > Thinh