Hi Felipe,

On 7/19/2017 1:16 PM, Felipe Balbi wrote:
> Hi,
>
> Manu Gautam <mgau...@codeaurora.org> writes:
>>> Manu Gautam <mgau...@codeaurora.org> writes:
>>>>> Manu Gautam <mgau...@codeaurora.org> writes:
>>>>> diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
>>>>>> index aea9a5b..b81547d 100644
>>>>>> --- a/drivers/usb/dwc3/gadget.c
>>>>>> +++ b/drivers/usb/dwc3/gadget.c
>>>>>> @@ -854,8 +854,13 @@ static void __dwc3_prepare_one_trb(struct dwc3_ep 
>>>>>> *dep, struct dwc3_trb *trb,
>>>>>>                          trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS_FIRST;
>>>>>>  
>>>>>>                          if (speed == USB_SPEED_HIGH) {
>>>>>> -                                struct usb_ep *ep = &dep->endpoint;
>>>>>> -                                trb->size |= 
>>>>>> DWC3_TRB_SIZE_PCM1(ep->mult - 1);
>>>>>> +                                unsigned int maxp = usb_endpoint_maxp(
>>>>>> +                                                        
>>>>>> dep->endpoint.desc);
>>>>>> +                                unsigned int rem = length % maxp;
>>>>>> +                                unsigned int mult = (length / maxp) & 
>>>>>> 0x3;
>>>>>> +
>>>>>> +                                trb->size |= DWC3_TRB_SIZE_PCM1(
>>>>>> +                                                rem ? mult : mult - 1);
>>>>> Manu, It seems to me like we shouldn't be relying on req->length. Which
>>>>> gadget driver are you using to test this?
>>>> f_uvc function is used.
>>>> In bus analyzer logs there are DATA2, DATA1 PIDs even for a 2K byte TRB
>>>> (also last packet of the video frame are always less than maxpacket size).
>>> Understood, yeah it makes sense, although I think your patch can be
>>> simplified. Seems to me that it should be enough to set PCM1 to
>>> req->length / usb_endpoint_maxp(), no?
>> Still need to take care of two things:
>> 1. Handle case if If req>length is more than 3K (buggy function driver)
>> 2. We don't need to send extra packet for isoc if length is multiple of maxp.
>> Hence, remainder must be checked.
>>
>>> Or, if we want to make use of ep->mult, we could:
>>>
>>>     unsigned int mult = ep->mult - 1;

It should be:
mult = 2;
Otherwise this logic works correctly only for 3K transfers. And for short 
packets '11' is
programmed as PCM1 (as mult becomes negative).
I didn't test updated patch for other mult values earlier, sorry about that. 
Will be sending
a fix for this.


>>>
>>>     if (req->length < (usb_endpoint_maxp() << 1))
>>>             mult--;
>> I think it should be <=
>> E.g. for 2k size only two transfers should take place)
>>
>>
>>>     if (req->length < usb_endpoint_maxp())
>>>             mult--;
>> <=
>>
>>>     trb->size |= DWC3_TRB_SIZE_PCM1(mult);
>>>
>>> how about that?
>>>
>> This also looks fine and I can send the updated patch.
> please do. While doing that, please also add a comment pointing out the
> USB Spec section you took it from and a simplified text of why we need
> it. This way, nobody will dare changing that part of the code without
> checking the spec ;-)
>
> IOW, add something akin to:
>
> /*
>  * USB Specification X.x Section Y states that "...."
>  *
>  * IOW, we should satisfy the following cases:
>  *
>  * i) req->length <= wMaxPacketSize
>  *    - DATA0
>  *
>  * ii) wMaxPacketSize < req->length <= (2 * wMaxPacketSize)
>  *    - DATA0, DATA1
>  *
>  * iii) (2 * maxPayloadSize) < req->length <= (3 * maxPayloadSize)
>  *    - DATA2, DATA1, DATA0
>  */
>
> Or something similar to that.
>

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to