Re: virtual hub and suspend/resume/reset questions

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

 



On Sun, 2017-06-11 at 10:09 -0400, Alan Stern wrote:
> 
> Under a non-emulated hub, the wakeup() function would start sending the
> wakeup signal upstream and then return.  The gadget's resume callback
> would not be invoked until later, probably at the end of the wakeup
> sequence (the API isn't specific about this; it would most likely
> depend on how the UDC hardware works).  So yes, you should break that
> call chain.

Right, that was my thinking too. I'll use a workqueue or a timer
interrupt. All of the suspend/resume/reset callback are interrupt safe
I assume (they are called from interrupt handlers on other drivers).

> > > 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).
> 
> Yes.  In the USB-2.0 spec, Figure 11-10, there are two different 
> transitions out of the Suspended state, depending on whether the resume 
> was initiated from upstream or downstream.

Ok thanks. I'll implement that.

> > 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).
> 
> That's right.
> 
> > It's a bit weird... but I'm happy to implement what the spec says.
> 
> There's a nice description of all this in section 7.1.7.7 of the spec.

Ok thanks.

> > > >  - 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 ?
> 
> > Ah, wait... the gadget driver has a ->disconnect() ... Maybe that's
> > what I should call in that case no ?
> 
> Yes.  Yanking the cable would remove Vbus power, so the UDC would see a
> disconnect rather than a suspend.  Or if the unplug was slow enough,
> so that the data pins in the USB cable lost contact long before the
> power pins, the UDC would see a suspend followed by a disconnect.
> 
> On the other hand, when the user on the host writes to the
> /sys/bus/usb/devices/.../remove file, that causes the host to turn off
> the port's enable feature.  To the device this looks the same as a
> suspend.

Ok. I don't have vbus detection upstream. Apparently nobody wires that
up on those systems (the chip is used as a BMC on server systems,
connected to the host USB, the connection is permanent, we will just
get resets as the host does things like turn on, reboot etc...).

I suppose if I simulated power control downstream I could do
disconnect, but I don't. From what you say, on port disable I should do
suspend instead. Mind you at least composite does the same thing for
both, so no big deal.

> Brief summary: Suspend is signalled by idle on the bus (the J state:
> D+ high and D- low) for more than 3 ms; reset is signalled by the SE0
> state (D+ and D- both low) on the bus -- if the connection is running 
> at full speed.  High speed is similar but more complicated.

Ok. I'll call suspend and turn off the underlying HW UDC device leg
when suspended so it stops responding to EP0 (and hopefully saves some
watts). I'll keep the CONNECTION status bit however, this one afaik
directly matches the pullup() calls.

Thanks !

Hopefully after I'm back from this long week-end I'll get to do a bit
of testing, I'll have a driver to submit soon.

Cheers,
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



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

  Powered by Linux