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 Peter,

On Wed, Jul 01, 2020 at 10:26:56AM +0800, Peter Chen wrote:
On Tue, Jun 30, 2020 at 3:15 PM Michael Grzeschik <mgr@xxxxxxxxxxxxxx> wrote:

On Mon, Jun 29, 2020 at 09:20:02PM +0000, Thinh Nguyen wrote:
>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.

This mask is used on many usb controllers and
everyone is defining their own.

drivers/usb/gadget/udc/mv_udc.h
34:#define USB_FRINDEX_MASKS    0x3fff

drivers/usb/gadget/udc/fsl_usb2_udc.h
116:#define     USB_FRINDEX_MASKS                       0x3fff


Even other drivers using the mask without defining it:

drivers/usb/misc/ftdi-elan.c
2224:   hc_fminterval &= 0x3fff;
2313:                              ((9 *hc_fminterval) / 10) & 0x3fff);

drivers/usb/chipidea/udc.c
1634:   ret = hw_read(ci, OP_FRINDEX, 0x3fff);

Hi Michael,

I can't find the above code for chipidea, where did you get?

I was greping my usb-wip stack where I have an extra
Patch for the get_frame callback implementation
of the chipidea/udc.c. I think I will have to post it.

The frame index value register is a standard EHCI register,
but for UDC, it is not a common register. UDC design is varied
for vendors.

Good to know. Is there any measure to find out if it is
there? I would add that limitation to the above mentioned patch.

Thanks,
Michael


drivers/usb/dwc3/gadget.c
1406:           test_frame_number = dep->frame_number & 0x3fff;
1453:   dep->frame_number &= 0x3fff;

drivers/usb/host/ohci-hcd.c
557:            ohci->fminterval = val & 0x3fff;

drivers/usb/host/xhci-ring.c
3980:   start_frame &= 0x3fff;

drivers/usb/host/ohci-dbg.c
635:                    rdata & 0x3fff);
641:                    rdata & 0x3fff);
647:                    rdata & 0x3fff);

drivers/usb/host/u132-hcd.c
1535:          ((9 * fi) / 10) & 0x3fff);
1605:           u132->hc_fminterval = temp & 0x3fff;

drivers/usb/host/ohci.h
701:    ohci_writel (ohci, ((9 * fi) / 10) & 0x3fff,

I could write a patch changing them all or at least
make a common gadget define.

What could be a common place for that?

On device level only it could be include/linux/usb/gadget.h
On whole usb level this could be include/uapi/linux/usb/ch9.h

Ideas?

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

Thanks!
Michael

--
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |


--
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

Attachment: signature.asc
Description: PGP signature


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

  Powered by Linux