Hi,
> Than either there is a bug in the UDC (or the UDC driver), or else the
> host doesn't wait for the Set-Config request to complete before sending
> the next request. What were the values of fsg->ep0_req_tag and
> exception_req_tag?
>From the printk added, the values of fsg->ep0_req_tag and exception_req_tag
>are:
fsg->ep0_req_tag 163, exception_req_tag 161
fsg->ep0_req_tag 168, exception_req_tag 167
fsg->ep0_req_tag 176, exception_req_tag 173
> By searching through the code in file_storage.c, you can easily see
> that fsg->ep0_req_tag gets set in only one place: the first line of
> fsg_setup(). It is a counter -- it goes up by one every time a new
> SETUP packet is received, marking the start of a new control transfer.
>
> You can also see that handle_exception() sets exception_req_tag to
> the value of fsg->exception_req_tag, and raise_exception() sets
> fsg->exception_req_tag to the value of fsg->ep0_req_tag. This means
> that exception_req_tag holds the counter value as of the time the
> exception started.
>
> If the values are different, it means that another control transfer
> started (fsg_setup() was called) between the time when the original
> exception was raised and the time when it was handled. If the UDC is
> working correctly, the only way for this to happen is if the host sends
> another control request without waiting for the first one to finish.
>
>> and rc is 0. In standard_setup_req(), case
>> USB_REQ_SET_CONFIGURATION, once i add the following code
>>
>> if (w_value == 0)
>> fsg->config = 0;
>>
>> just before the break; statement, the "Device Descriptor
>> Test-Addressed State" can pass. It seems that Get-Config request from
>> host cannot wait, so i have to return the latest config value in
>> response to the request.
>
> Almost certainly, the problem is that the UDC told the host that the
> Set-Config request was finished before it should have. The host
> thought the request was finished, so it sent the next request -- the
> Get-Config -- but the gadget driver was still carrying out the
> Set-Config.
Yes, this should be the root cause. For the setup stage of Set-Config
request, the UDC driver can handle it well. But for the status stage
of Set-Config request, somehow it is not handled correctly. When UDC
driver receives the endpoint 0 IN token, it only clears the interrupt
request. It will not send the Data1 packet unless usb_ep_queue() is
called.
Somehow, before handle_exception() gets the chance to call
do_set_config(), host sends next request.
> DELAYED_STATUS tells fsg_setup() not to call ep0_queue(). It means
> that the request isn't finished yet, so the status isn't known. The
> status will be reported later, when the request is finished.
>
> handle_exception() is used for things that cannot be carried out in
> interrupt context. fsg_setup() runs in an interrupt handler, so it
> can't call do_set_config() or do_set_interface() -- those routines need
> to run in process context. Therefore the USB_REQ_SET_CONFIGURATION
> code raises an exception; when the fsg thread handles the exception, it
> calls do_set_config().
>
> When your UDC driver calls the gadget driver's .setup() function, how
> does it handle the return value?
The code is as below:
status = dev->driver->setup(&dev->gadget, &usb_ctrlrequest);
if (status < 0)
{
dev->protocol_stall = 1;
}
else if (status == (DELAYED_STATUS))
{
/*NAK the IN packet from host*/
}
Thanks,
victor
--
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