On Wed, 3 Jul 2013, Victor Yeo wrote: > Hi, > > > I can't tell what's going on in your log. Look at the > > FSG_STATE_CONFIG_CHANGE case in handle_exception(). Here's the code: > > > > rc = do_set_config(fsg, new_config); > > if (fsg->ep0_req_tag != exception_req_tag) > > break; > > if (rc != 0) // STALL on errors > > fsg_set_halt(fsg, fsg->ep0); > > else // Complete the status stage > > ep0_queue(fsg); > > break; > > > > It calls do_set_config(). After that, fsg->ep0_req_tag should be equal > > to exception_req_tag and rc should be equal to 0. Therefore the code > > will call ep0_queue(), which calls usb_ep_queue(). > > I found out from printk, the fsg->ep0_req_tag and exception_req_tag > are not equal, 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? 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. > In fact, the "Device Descriptor Test-Addressed State" sometimes > passes, sometimes fails after my modification. What is the reason of > DELAYED_STATUS in USB_REQ_SET_CONFIGURATION, and the use of > handle_exception() to call do_set_config()? 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? Alan Stern -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html