Hi,

On 9/8/2017 2:34 AM, Felipe Balbi wrote:
> Felipe Balbi <[email protected]> writes:
>> Thinh Nguyen <[email protected]> writes:
>>
>>> Hi Felipe,
>>>
>>> On 9/7/2017 12:16 AM, Felipe Balbi wrote:
>>>>>>>     drivers/usb/dwc3/gadget.c | 8 +++++---
>>>>>>>     1 file changed, 5 insertions(+), 3 deletions(-)
>>>>>>>
>>>>>>> diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
>>>>>>> index 9e41605a..6b299c7 100644
>>>>>>> --- a/drivers/usb/dwc3/gadget.c
>>>>>>> +++ b/drivers/usb/dwc3/gadget.c
>>>>>>> @@ -191,14 +191,16 @@ void dwc3_gadget_giveback(struct dwc3_ep *dep, 
>>>>>>> struct dwc3_request *req,
>>>>>>>     
>>>>>>>         req->started = false;
>>>>>>>         list_del(&req->list);
>>>>>>> -       req->trb = NULL;
>>>>>>>         req->remaining = 0;
>>>>>>>     
>>>>>>>         if (req->request.status == -EINPROGRESS)
>>>>>>>                 req->request.status = status;
>>>>>>>     
>>>>>>> -       usb_gadget_unmap_request_by_dev(dwc->sysdev,
>>>>>>> -                                       &req->request, req->direction);
>>>>>>> +       if (req->trb)
>>>>>> This check does not account for control data transfer. TRBs for ep0 are
>>>>>> not set to its req->trb. ep0out request needs to be unmapped, otherwise
>>>>>> device will receive bogus data.
>>>>>>
>>>>>> Our internal test showed that the device failed to interpret control
>>>>>> data from host. I bisected to this patch.
>>>>
>>>> what was the testing? How can I reproduce it?
>>>
>>> This is a regression. The internal test found the issue when it does a
>>> 3-stage Control Write Transfer. You can reproduce this issue with just 1
>>> out data packet of size > 0. Read and check the data on control request
>>> completion.
>>
>> okay, is this enough to fix the problem for you?
>>
>> modified   drivers/usb/dwc3/ep0.c
>> @@ -48,6 +48,9 @@ static void dwc3_ep0_prepare_one_trb(struct dwc3_ep *dep,
>>      dwc = dep->dwc;
>>      trb = &dwc->ep0_trb[dep->trb_enqueue];
>>   
>> +    if (!req->trb)
>> +            req->trb = trb;
>> +
>>      if (chain)
>>              dep->trb_enqueue++;
> 
> sorry, no. this is totally wrong :-) Here's a better version:
> 
> modified   drivers/usb/dwc3/ep0.c
> @@ -990,6 +990,8 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
>                                        DWC3_TRBCTL_CONTROL_DATA,
>                                        true);
>   
> +             req->trb = &dwc->ep0_trb[dep->trb_enqueue - 1]; > +
>               /* Now prepare one extra TRB to align transfer size */
>               dwc3_ep0_prepare_one_trb(dep, dwc->bounce_addr,
>                                        maxpacket - rem,
> @@ -1015,6 +1017,8 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
>                                        DWC3_TRBCTL_CONTROL_DATA,
>                                        true);
>   
> +             req->trb = &dwc->ep0_trb[dep->trb_enqueue - 1]; > +
>               /* Now prepare one extra TRB to align transfer size */
>               dwc3_ep0_prepare_one_trb(dep, dwc->bounce_addr,
>                                        0, DWC3_TRBCTL_CONTROL_DATA,
> @@ -1029,6 +1033,9 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc,
>               dwc3_ep0_prepare_one_trb(dep, req->request.dma,
>                               req->request.length, DWC3_TRBCTL_CONTROL_DATA,
>                               false);
> +
> +             req->trb = &dwc->ep0_trb[dep->trb_enqueue];
> +
>               ret = dwc3_ep0_start_trans(dep);
>       }
> 
> (didn't even compile test)
>   
> 

Yes this works.

Thanks,
Thinh
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to