Re: Question about USB keyboard remote wakeup from hibernation

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

 



On Tue, 2011-04-12 at 14:04 -0400, Alan Stern wrote:
> On Tue, 12 Apr 2011, Andiry Xu wrote:
> 
> > On Thu, 2011-04-07 at 10:47 -0400, Alan Stern wrote:
> > > Please set up your email client to wrap lines after 72 columns or so.
> > > 
> > > On Thu, 7 Apr 2011, Xu, Andiry wrote:
> > > 
> > > > Hi,
> > > > 
> > > > Currently I'm facing a problem on USB remote wakeup from hibernation.
> > > > When plug a USB1.1 keyboard to EHCI/OHCI port, press button during suspend and hibernation can wakeup the system; However, when I plug the keyboard to xHCI port, press button can only wakeup the system from suspend, but not from hibernation.
> > > > 
> > > > I think the driver should treat the USB keyboard remote wakeup the same way for both suspend and hibernation(set remote wakeup request to the device, suspend it and the host, etc). I don't know why remote wakeup for suspend and hibernation behaves differently on xHCI port. Any suggestions? 
> > > 
> > > Can you post the dmesg log (with CONFIG_USB_DEBUG enabled) and a usbmon 
> > > trace?
> > > 
> > > > Another question is I can see usb_port_suspend() and xhci_pci_suspend() getting called during suspend, but I cannot see them called during hibernation, either by adding print message and using ftrace. Are they not called at all during hibernation, or just print message and ftrace fails to catch it? Thanks. 
> > > 
> > > They should be called, if everything is working right.  The dmesg log 
> > > will help answer these questions.
> > > 
> > 
> > Please see the attached usbmon trace and dmesg:
> > 1.mon.out/dmesg1: S3 with USB keyboard plugged to xHCI controller as usb
> > 7-3
> > 2.mon.out/dmesg2: S4 with USB keyboard plugged to xHCI controller as usb
> > 7-3 (use power button to wakeup)
> > 3.mon.txt/dmesg3: S3 with USB keyboard plugged to OHCI controller as usb
> > 3-5
> > 4.mon.txt/dmesg3: S4 with USB keyboard plugged to OHCI controller as usb
> > 3-5
> 
> Hmmm.  These logs really aren't good enough, although it may not be 
> possible for you to do much better.
> 
> Hibernation is a three-stage procedure.  In the first stage, devices
> are frozen and then a memory image is created.  In the second stage,
> devices are thawed and then the memory image is written to disk.  In
> the third stage, devices are powered off (the same as suspend).
> 
> Resume from hibernation involves two more stages.  In the fourth stage, 
> devices are frozen and then the memory image is copied into RAM.  In 
> the fifth stage, devices are restored (the same as resume).
> 
> This means that when you run the dmesg command after resuming, what you
> get contains the log messages only from the first and fifth stages.  
> The messages from the second, third, and fourth stage are lost because
> they aren't part of the memory image.  If you can set up a serial
> console then you'll be able record the entire kernel log without losing
> anything.  As an example, when I need to test with a serial console, I 
> add this to the kernel boot command line:
> 
> 	console=ttyS0,115200 console=tty0 no_console_suspend
> 
> If you can find a test computer with a serial port (I don't think a
> USB-RS232 device is good enough), something like that should work.
> 
> Thus: usb_port_suspend() is called during the third stage, but for this
> reason it don't show up in the dmesg2.txt file.  That answers one of
> your questions.  On the other hand, xhci_pci_suspend() gets called 
> during the first, third, and fourth stages -- and in fact, dmesg2.txt 
> does contain this line:
> 
> [  709.722482] usb usb7: bus suspend
> 
> Another part of the problem may be that during the frezzing stages, USB
> devices are not suspended but the bus_suspend methods _are_ called.  
> This causes no difficulty for [UOE]HCI, but it might for xHCI.
> 
> As for why the keyboard wakeup doesn't work, I can't tell.  Maybe the
> second stage (thawing) fails somehow, so the wakeup mechanism never 
> gets set up properly.
> 

Thanks for the elaborate explanation, that's really helpful.

I've not got a serial console but I managed to catch some call trace
using a very simple but effective method: use outb(data, 0x80) and check
the LED display on the motherboard.

xhci_bus_suspend() will check all the ports and suspend them if they are
in U0 state. this makes things different for suspend and hibernation.

During system suspend, the call trace is like this:
usb_port_suspend():
    Set REMOTE_WAKEUP request to the device;
    Suspend the port;
xhci_bus_suspend():
    //The port is already suspended
xhci_pci_suspend()
    Suspend the host;

During system hibernation, the call trace is like this:
xhci_bus_suspend():
    Suspend the port, since it's in U0 state;
usb_port_suspend():
    No REMOTE_WAKEUP request is sent to the device, maybe because it's
suspended?
    Suspend the port;
xhci_pci_suspend():
    Suspend the host;

So remote wakeup is not working.

I made a small test, skip the port suspend part in xhci_bus_suspend():
xhci_bus_suspend():
    //Skip the port suspend part;
usb_port_suspend():
    REMOTE_WAKEUP request is sent to the device;
    Suspend the port;
xhci_pci_suspend():
    Suspend the host;

And by doing this, press the USB keyboard on xHCI can wakeup the system
from hibernation.

The xhci bus suspend/resume is mainly copied from EHCI bus
suspend/resume method, in which EHCI suspend all the ports during bus
suspend. Seems it should be modified for xHCI. Any suggestions?

Thanks,
Andiry

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