Re: [PATCH v3 1/2] usb: dwc3: gadget: make starting isoc transfers more robust

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

Michael Grzeschik wrote:
> From: Michael Olbrich <m.olbrich@xxxxxxxxxxxxxx>
>
> Currently __dwc3_gadget_start_isoc must be called very shortly after
> XferNotReady. Otherwise the frame number is outdated and start transfer
> will fail, even with several retries.
>
> DSTS provides the lower 14 bit of the frame number. Use it in combination
> with the frame number provided by XferNotReady to guess the current frame
> number. This will succeed unless more than one 14 rollover has happened
> since XferNotReady.
>
> Start transfer might still fail if the frame number is increased
> immediately after DSTS is read. So retries are still needed.
> Don't drop the current request if this happens. This way it is not lost and
> can be used immediately to try again with the next frame number.
>
> With this change, __dwc3_gadget_start_isoc is still not successfully in all
> cases bit it increases the acceptable delay after XferNotReady
> significantly.
>
> Signed-off-by: Michael Olbrich <m.olbrich@xxxxxxxxxxxxxx>
> Signed-off-by: Michael Tretter <m.tretter@xxxxxxxxxxxxxx>
> Signed-off-by: Michael Grzeschik <m.grzeschik@xxxxxxxxxxxxxx>
>
> ---
> v1 -> v2: - removed last_frame_number from struct
>            - included rollover variable
> v2 -> v3: - moved the calculation before the retry loop
>            - skipping the calculation if bInterval > 14
>
>   drivers/usb/dwc3/gadget.c | 19 +++++++++++++++++++
>   1 file changed, 19 insertions(+)
>
> diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
> index 8de6f10d335e1c0..7ad85a7d06f70bf 100644
> --- a/drivers/usb/dwc3/gadget.c
> +++ b/drivers/usb/dwc3/gadget.c
> @@ -1463,6 +1463,7 @@ static int dwc3_gadget_start_isoc_quirk(struct dwc3_ep *dep)
>   
>   static int __dwc3_gadget_start_isoc(struct dwc3_ep *dep)
>   {
> +	const struct usb_endpoint_descriptor *desc = dep->endpoint.desc;
>   	struct dwc3 *dwc = dep->dwc;
>   	int ret;
>   	int i;
> @@ -1480,6 +1481,24 @@ static int __dwc3_gadget_start_isoc(struct dwc3_ep *dep)
>   			return dwc3_gadget_start_isoc_quirk(dep);
>   	}
>   
> +	if (desc->bInterval <= 14) {
> +		u32 frame = __dwc3_gadget_get_frame(dwc);
> +		bool rollover = frame < (dep->frame_number & 0x3fff);
> +
> +		/*
> +		 * frame_number is set from XferNotReady and may be already
> +		 * out of date. DSTS only provides the lower 14 bit of the
> +		 * current frame number. So add the upper two bits of
> +		 * frame_number and handle a possible rollover.
> +		 * This will provide the correct frame_number unless more than
> +		 * rollover has happened since XferNotReady.
> +		 */
> +
> +		dep->frame_number = (dep->frame_number & ~0x3fff) | frame;
> +		if (rollover)
> +			dep->frame_number += BIT(14);
> +	}
> +
>   	for (i = 0; i < DWC3_ISOC_MAX_RETRIES; i++) {
>   		dep->frame_number = DWC3_ALIGN_FRAME(dep, i + 1);
>   

I think it's cleaner to create a mask for 0x3fff, but I can see how it 
can arguably clearer for not using a macro also. It's fine to me either way.

For both patches in this series:
Reviewed-by: Thinh Nguyen <thinhn@xxxxxxxxxxxx>

Thanks,
Thinh





[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux