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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to