On Sat, 2017-06-10 at 12:58 -0400, Alan Stern wrote: > On Sat, 10 Jun 2017, Benjamin Herrenschmidt wrote: > > with the obvious resume case above I assume. A port reset > > would probably also "resume" though I would forward a reset to the > > gadget rather than a resume, right ? (but clear my "suspended" state > > flag). > > IIRC, according to the USB spec a host is never supposed to issue a > reset request to a suspended port. It has to resume the port first. > But yes, if you did get a reset then you would clear the suspend > status and forward the reset to the gadget. I was thinking more of the upstream port detecting a bus reset. > > Now where things become interesting: > > > > - A wakeup() from the gadget. If the port is suspended but nothing > > else above it, what do I do ? Mark the port resumed and move on ? Do I > > need to call the gadget resume() callback ? > > Assuming the vhub itself is not suspended, mark the port as resumed and > invoke the callback, but also set the port-suspend-change bit in the > port's status register so that the port's bit will be set in the next > reply on the vhub's interrupt endpoint. Ok. So just to make sure I get you right, when the function calls wakeup(), the UDC driver, from within that wakeup, will call back into the function resume() ? Or do I need to somewhat break that call chain and call back resume() later ? > > - If I get a suspend from the host. IE. the top level port of the vhub > > detects a suspend state on the bus (the HW signals that to me). I > > assume here I should call "suspend" on all my downstream gadgets, at > > least those who weren't already suspended. But do I also change the > > internal state to "suspended" for all the ports ? > > Yes, invoke the suspend callbacks, but do not change the downstream > port statuses. Ok. > > - Then I get a resume from the host, ie, the upstream bus resumes, > > should I resume *all* my downstream ports ? > > Only the ones where the port status says that the port is not > suspended. Ok, so we "keep" the explicit port status that was set by the host. Thanks. > > What if a downstream port > > had been explicitly suspended with SetPortFeature before the host > > suspended the whole bus, will the bus resume also clear that suspend > > state or should that port remain suspended until a ClearPortFeature or > > reset occurs ? > > It remains suspended. Ok. > But there's one other interesting case you have forgotten about. > That's where the vhub is suspended when one of the gadgets sends a > wakeup request. You have to clear the suspend status on all the > downstream ports (and set the port-suspend-change status bits) and send > a wakeup request on your upstream port. Ok. So that's interesting and very weird in a way. That means that if the host has explicitly suspended let's say port A and B, and the vhub itself got suspended (thus suspending C, D and E but without affecting their port status), what happens differs whether the wakeup comes from the host (global bus wakeup) vs. a suspend request of one of the devices (let's say A). In the first case, only C, D and E get woken up. But if A triggers a wakeup, it will also wakeup B. Or if C triggers a wakeup, it will wakeup A and B (while a wakeup from the host wouldn't have woken those up). It's a bit weird... but I'm happy to implement what the spec says. > > - I assume a bus reset (after set address) will result in broadcasting > > a reset to all the downstream ports. What if they were suspended, > > should I call resume first then reset or just reset on the gadgets ? > > No, a reset sent to the vhub does not broadcast anything to the > downstream ports. It merely disables all of them and clears all their > status bits (the connect and connect-change bits will then get set if a > gadget is bound to the port -- the exact timing depends on whether > you want to emulate port power switching since a reset will turn off > the port's power feature). To the gadgets, this should appear to be > the same as a suspend -- in fact, you should invoke their suspend > callbacks. Likewise if the host clears a port's enable feature. Oh interesting. I was assuming a clearing of port enable to be a reset rather than a suspend. So for example, from the perspective of an ordinary gadget today (ie not my driver), if I yank the cable, what they see is a suspend ? > > - Should my virtual hub "emulate" the various timings/delays of a hub > > switching between those different states ? Esp. from resume or reset to > > enabled, is it ok if it's more/less immediate ? > > Immediate is okay. The only time anyone would care would be if they > are doing some bizarre test for conformance to the spec, and probably > not even the USB CV would test for state changes occurring too quickly. Ok. > > - When a downstream port is suspended, I assume I need to actively > > block activity on its pipes ? ie, not forward setup packets and NAK > > everything to it, or is this unnecessary ? > > I don't know the details of how your hardware works. For "downstream" the HW doesn't have a suspend state but I can manually disable the device response to EP0 and disable the other EPs. > In theory, you > should disable those endpoints completely -- don't send ACKs, don't > send NAKs, don't send or receive anything. And of course this implies > that you never receive any setup packets, so naturally you never > forward any of them. Ok. I might have to run Paulus home made analyzer on it to make sure the HW does what I think it does, the spec is rather poor. Thanks ! Cheer, Ben. -- 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