Re: [RFC v2 7/9] USB/xHCI: Support device-initiated USB 3.0 resume.

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

 



On Fri, Jan 27, 2012 at 03:19:08PM -0500, Alan Stern wrote:
> On Fri, 27 Jan 2012, Sarah Sharp wrote:
> 
> > > Do we really need to worry about this?  The worst that can happen is 
> > > the parent hub suspends, then the device requests another wakeup and 
> > > sends another notification.
> > 
> > The device will send another device notification, but it won't attempt
> > to signal a resume, because from its standpoint, the link state is still
> > in U0.  Here's why:
> > 
> > All USB 3.0 hubs are powered by wall worts.  USB 2.0 hubs suspend after
> > they haven't seen an SOF for a period of time, but they got rid of SOFs
> > for USB 3.0 devices (too much power consumption).  USB 3.0 devices and
> > hubs communicate via link commands to transition between U0, U1, U2, and
> > U3.  In this case, the child device thinks its link is in U0, and will
> > continue to do so until it gets an LGO_U3 request and responds with an
> > LAU (link accept U-state).  But the parent hub only sends an LGO_U3 if
> > SW set that port's link state to U3.  Obviously SW won't set that link
> > state to U3 because we think the device is still suspended.
> 
> Are you certain this requires software intervention?  As an example,
> 10.3.1.5 gives conditions under which a hub's downstream link will
> automatically go back to U3 from U0.  (See the second-to-last paragraph 
> in 10.4.2.6.)  No software activity is needed.
> 
> Of course, that's not the case you're talking about here.  10.3.1.5
> describes what happens when a device is plugged into a suspended hub,
> and you're talking about what happens when a hub is suspended while one
> of its children is active.

Yes, that is the case in question.

> > So what does the USB 3.0 hub do if it receives an LG0_U3 request on its
> > upstream port, and one of its downstream ports is in a higher-power link
> > state (U0 in our case)?
> > 
> > The USB 3.0 spec is ambiguous about this behavior of the hub.  The smart
> > thing to do would be accept the LGO_U3 command and immediately signal a
> > resume.
> 
> Or else accept the command and send a similar command to the downstream 
> port.

LGO commands are only sent between link partners.  They are never
forwarded it downstream.  Hubs are explicitly barred from sending LGO_U3
commands without SW setting the U3 link state for that port.  The USB
3.0 spec calls out that there is no global suspend for USB 3.0 devices,
only selective suspend.

> >  However, in talking with the hub chapter owner, he says there
> > is some ambiguity about whether the hub will do that, or simply ignore
> > the LGO_U3 command.
> > 
> > If it does ignore the LGO_U3 command, the results are pretty disastrous.
> > After automatically trying the U3 transition three times, the parent hub
> > will place the port in SS.Inactive, and signal a port status change
> > event to SW.  Then we have to issue a warm reset on that port, and I
> > think that means we'll have to re-enumerate the device.
> 
> And there doesn't seem to be much we can do to prevent this, if the hub 
> doesn't cooperate.

Yeah, I think we can only try to not run into this corner case, or
possibly have a dynamic blacklist for hubs that exhibit the SS.Inactive
state after a suspend.  I have a cheapo early prototype that always
refuses LGO_U3, so it should be easy to test.

> > So I would like to avoid this ambiguity by starting the resume from the
> > roothub down when the roothub indicates there was resume signaling.  Of
> 
> Okay, the root hub knows that it resumed one of its ports, but it 
> doesn't know where the remote wakeup request came from.  I guess the 
> thing to do is interpret the root hub's data as a wakeup request, and 
> have hub_activate()'s HUB_RESUME case check for downstream ports in U0.

Ok, I'll have to look at that.  I take it you would rather that
hub_activate() looked at the port link state than use the wakeup bits in
hub_events()?

> > > Also, what you're saying makes no sense.  We have no way to know that
> > > the parent hub should be prevented from suspending, because we don't
> > > realize that anything special has happened until we receive the
> > > notification.
> > 
> > We do, if the link between hub A and the roothub is in U3.  Then the
> > roothub will reflect the resume signaling, the xHCI driver gets a port
> > status change event, and it can call usb_super_speed_remote_wakeup() for
> > the roothub.
> 
> You don't need to call that routine.  Just make khubd interpret the 
> C_PORT_LINK_STATE status for root hub ports as indicating a wakeup 
> event.  That's the bit which indicates the root hub reflected the 
> resume signal, right?

C_PORT_LINK_STATE is only set when a host-initiated resume completes.
It is not set when a device-initiated resume completes.  That's
different than USB 2.0 hubs.

That's why hub_events() can't simply look at the hub status buffer
(hub->events).  The hub will not indicate an event on a port for a
device-initiated resume.  That's why I was trying to use the wakeup_bits
to avoid having to poll every single port when hub_events() was called.

Sarah Sharp
--
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