Re: virtual hub and suspend/resume/reset questions

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, 10 Jun 2017, Benjamin Herrenschmidt wrote:

> Hi !
> 
> The USB spec is twisting my brain sideways trying to figure out how to
> properly handle suspend/resume in the case of the aspeed vHub.
> 
> Reminder: This is a combo-gadget HW that has 5 UDC "ports" (gadgets)
> and a virtual hub above them, so it looks to the host as a hub with 5
> ports, the hub functionality is partially done in HW, partially in SW
> in my driver.
> 
> So first what I think is the easy case of explicit port suspend/resume
> by SetPortFeature/ClearPortFeature.
> 
> In that case, I can just call the gadget suspend() callback for that
> port, keep track that the port is suspended, and *maybe* also disable
> the HW so it doesn't respond on any pipe.
> 
> Same goes 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.

> 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.

>  - 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.

>  - 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.

>  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.

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.

>  - 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.

>  - 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.

>  - 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.  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.

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



[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux