On Tue, Aug 21, 2012 at 2:34 PM, Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> wrote: >> But some requests are handled entirely in hardware, including the status phase: >> >> SET_ADDRESS >> SET_CONFIGURATION >> SET_INTERFACE >> SET_FEATURE >> CLEAR_FEATURE >> GET_FEATURE > > I assume the features in question are endpoint-halts and > remote-wakeup-enable. It's hard to think of any other features that > could be handled in hardware. Yes, endpoint-halt is what I've seen in my testing. Not sure on remote wakeup. > (BTW, what happens if one of these requests arrives before a previous > control IRQ has been acknowledged by the CPU? Does the old data in the > registers get overwritten and lost, or does the UDC hold off on > carrying out the new request?) There are separate IRQ bits for SET_CONFIGURATION, SET_INTERFACE, and "generic setup packet." The driver processes them in order. Consecutive SET_INTERFACE requests could potentially get "lost," but the controller will remember the value set in the most recent request. > I can't imagine how any gadget driver could hope to handle a mess like > this. For instance, suppose a Set-Config operation fails. There's no > way for the driver to tell the host, because the hardware has already > said that the operation succeeded. Right - but looking on the bright side: 1) At least in my experience, most hosts will send a valid SET_CONFIGURATION request so the error path won't be needed. If it is needed, it won't do anything really bad like hanging the interface. 2) All of this complexity is hidden inside one UDC driver, and did not require hacking up the rest of the gadget layer. 3) After many months of struggling to get things right, the driver can finally pass "testusb". > Anyway, you don't need to workqueue to manage this -- just a queue of > pending control requests. You should be able to do everything in > interrupt context, especially since you will ignore any responses the > driver submits on ep0 for these transfers. Well, in the example from my last email, I don't get any new interrupts after SET_INTERFACE. So after the gadget driver queues the response to the spoofed SET_CONFIGURATION packet, I need to schedule a workqueue (or tasklet, or timer, or something) to run the next setup callback in a context where the gadget driver isn't holding any spinlocks.