Search

Ubuntu - Resume your computer from any USB device (keyboard, mouse, remote, ...)

Contents[Hide]

Ubuntu

With the arrival of Gnome Shell, one major step has been taken : by default you can't switch-off your computer !

In fact, the only menu available is Suspend. You have to press ALT at the same time to see the Switch-off menu. You will find lots of topics about this strange evolution on the net, with lots of furious people who still want to keep the power of switching off their computer.

But, if you think twice about it, suspend / resume is one of the revolution of modern appliances : who is still switching-off a TV set, a video player or an ADSL box ?
Almost nobody ! Now, you suspend it from your remote. So why not to handle your favorite computer the same way ?

usb-symbol Even if it is consuming a little bit of power, suspend state is having a very strong advantage : it takes almost no time to resume to working condition.

Who is ready to wait for 1 minute or more to check his mails, when 5 seconds are enough to resume a computer with thunderbird already open ?

Under Ubuntu, the only trouble is that your USB input devices (keyboard, mouse, MCE remote, …) are not fully configured by default to be used to resume from a suspend mode.

This guide will explain how to configure your USB input devices to be able to wake-up your suspended computer. As a result, you will be able to wake-up your Ubuntu computer with :

  • a simple key press on your keyboard
  • a click on your mouse center button
  • the power button of your MCE remote

It has been written on a Ubuntu Precise 12.04, but should be applicable with any Linux flavor using a kernel version prior to 3.10.
As USB power management has changed drastically in kernel 3.10 +, this article is not applicable for kernel 3.10+.

Before going further thru that article, just make sure that your BIOS has been set-up properly to allow Wake Up on USB feature.
As this is heavily dependant on the hardware, you may have to go thru your BIOS options to be sure that it is enabled.

Not all USB devices are able to handle suspend mode, while they get a low power supply.
But most modern USB HID devices (Human Interface Devices) will handle it smartly.

1. Technical Stuff

If your only goal is to get your USB devices handling your computer resume, you don't need to read this part, go straight to the next paragraph.

Under SYSFS, a typical USB device connexion chain will ressemble something like /sys/devices/pci0000:00/0000:00:1d.0/usb5/5-0:1.0.

To be able to resume your computer with this USB device, you will need to have a wake-up power supply on every active device of the chain. In this way, even with the computer suspended, a minimum power will be supplied to the devices, so that they can send the wake-up signal.

With SYSFS, the power supply of an active device is controlled by its ./power/wakeup file. By simply writing enabled in that file, you are configuring it to get the wakeup power supply during suspended mode.

As an example, to enable wakeup power supply for the root PCI bus we need to write enabled in /sys/devices/pci0000:00/0000:00:1d.0/power/wakeup

# sudo sh -c "echo enabled > /sys/devices/pci0000:00/0000:00:1d.0/power/wakeup"

So to enable a USB device to be used to resume your computer, you simply need to enable every active device on the connexion chain from the PCI bus till the device itself.

It's as simple as that.

2. What has to be done

To enable resume from any USB input devices, we will follow these steps :

  1. List all USB devices connected to the computer (other than hubs)
  2. Select the devices we want to use for resuming the computer
  3. Create a udev rule for every device. The rule will be called at every boot or device connexion

The udev rule will take care of the power configuration of the connexion chain from the device till the PCI bus.

We will need 2 different scripts :

  • one script to list & select the devices and to create the udev rules
  • one script to do the real job, configuring the USB device connexion chain for resume

3. Pre-Requisite

The scripts we will write depend on these tools :

  • zenity
  • udevadm
  • notify-send

udevadm and notify-send are provided by default by Ubuntu, respectively by the udev and libnotify-bin packages.

We just need to install zenity package :

# sudo aptitude install zenity

As we will be using the PCI and USB vendors and products database, lets get the latest update :

# sudo update-usbids
--2012-05-17 12:19:13-- http://www.linux-usb.org/usb.ids
...
Done.

4. Udev Resume Script

This script will be called by the udev rules we will create later in this article.

It will be called for every selected device :

  • when it is connected / disconnected
  • at every boot

This script is mainly a loop running thru the device connexion chain, starting from the device and going upward till the PCI root. At every stage, if the power/wakeup subdirectory file exists, it enables it. At the end, an event is logged under /var/log/syslog with the name of the device.

So, lets create the script and give it execute rights :

# sudo gedit /usr/local/sbin/enable-wakeup
# sudo chmod +x /usr/local/sbin/enable-wakeup

/usr/local/sbin/enable-wakeup

#!/bin/bash
#
# Script to enable a USB devices to be used to resume computer from sleep
#
# Depends on udevadm package
# 09/05/2012 - V1.0 by Nicolas Bernaerts

# if device has been removed, exit
[ "$ACTION" = "remove" ] && exit 0

# set PATH as it is not set for udev scripts
PATH="/usr/sbin:/usr/bin:/sbin:/bin"

# set device SYSFS path
DEVICE_SYSFS="/sys$1"
CURRENT_SYSFS=$DEVICE_SYSFS

# get device product and vendor name from parent SYSFS
DEVICE_VENDOR=`udevadm info --query=all -p "$CURRENT_SYSFS/../" | grep "ID_VENDOR_ID=" | cut -d "=" -f 2`
DEVICE_PRODUCT=`udevadm info --query=all -p "$CURRENT_SYSFS/../" | grep "ID_MODEL_ID=" | cut -d "=" -f 2`
DEVICE_LABEL=`lsusb | grep "${DEVICE_VENDOR}:${DEVICE_PRODUCT}" | sed 's/^.*[0-9a-f]\:[0-9a-f]* \(.*\)$/\1/g'`

# loop thru the SYSFS path, up to PCI bus
CARRY_ON=1
while [ $CARRY_ON -eq 1 ]
do
  # get the first three letters of current SYSFS folder
  FIRST_LETTERS=`basename $CURRENT_SYSFS | sed 's/^\(...\).*$/\1/g'`

  # if current SYSFS is PCI bus, stop the loop
  if [ "$FIRST_LETTERS" = "pci" ] || [ "$FIRST_LETTERS" = "/" ] ; then
    CARRY_ON=0

  # else,
  else
    # if possible, enable wakeup for current SYSFS
    WAKEUP_FILE="${CURRENT_SYSFS}/power/wakeup"
    if [ -f $WAKEUP_FILE ]; then
      echo "enabled" > $WAKEUP_FILE
    fi

    # go to father directory of current SYSFS
    CURRENT_SYSFS=`dirname $CURRENT_SYSFS`
  fi
done

# log the action
LOG_HEADER="USB device ${DEVICE_VENDOR}:${DEVICE_PRODUCT}"
logger "${LOG_HEADER} - Description : ${DEVICE_LABEL}"
logger "${LOG_HEADER} - SysFS path  : ${DEVICE_SYSFS}"
logger "${LOG_HEADER} - Device is enabled to handle suspend/resume"

With latest udev version, the new script is taken into account as soon as it is saved.

5. Device Selection Script

The following script is a helper script.

It's main role is to :

  • list all connected USB devices
  • let you select the devices you want to be able to resume from
  • generate the udev rule for every selected device

The script has to be created as root :

# sudo gedit /usr/local/sbin/select-resume-devices
# sudo chmod +x /usr/local/sbin/select-resume-devices

/usr/local/sbin/select-resume-devices

#!/bin/bash
#
# Script to create resume udev rules for USB devices
#
# Depends on zenity
# 09/05/2012 - V1.0 by Nicolas Bernaerts

# udev file to generate
UDEV_FILE="/etc/udev/rules.d/90-hid-wakeup-enable.rules"

# set separator as CR
IFS=$'\n'

# list all USB devices, excluding root & hubs
LIST_DEVICE=(`lsusb | grep -v "0000:0000" | grep -iv "hub" | sed 's/^.*[0-9a-f]\:[0-9a-f]* \(.*\)$/\1/g'`)

# loop thru the devices array to generate zenity parameter
for DEVICE in "${LIST_DEVICE[@]}"
do
  # if needed, remove [xxx] from device name as it gives trouble with grep
  DEVICE=`echo "$DEVICE" | sed 's/\[.*\]//g'`

  # add it to the parameters list
  ARR_PARAMETER=( FALSE ${DEVICE} ${ARR_PARAMETER[@]} )
done

# display the dialog box to choose devices
TITLE="Wakeup - Enable USB devices"
TEXT="Please, select USB devices you want to use to resume your computer"
CHOICE=`zenity --list --width=600 --height=250 --text=$TEXT --title=$TITLE --checklist --column "Select" --column "Device name" "${ARR_PARAMETER[@]}"`

# slit the device choice into an array
IFS="|" read -a ARR_CHOICE <<< "$CHOICE"

# if at least one device has been selected, initialise udev rules file
[ ${#ARR_CHOICE[@]} -gt 0 ] && echo "# udev rule for USB wake-up of selected devices" > $UDEV_FILE
[ ${#ARR_CHOICE[@]} -gt 0 ] && echo "#" >> $UDEV_FILE

# loop thru the selected devices to create udev rules
for DEVICE_NAME in "${ARR_CHOICE[@]}"
do
  # get current device data
  DEVICE_DATA=`lsusb | grep "${DEVICE_NAME}" | sed 's/^.*ID \([0-9a-f]*\):\([0-9a-f]*\).*$/\1|\2/g'`
  DEVICE_VENDOR=`echo $DEVICE_DATA | cut -d"|" -f1`
  DEVICE_PRODUCT=`echo $DEVICE_DATA | cut -d"|" -f2`

  # create udev rule for current device
  DEVICE_RULE="SUBSYSTEM==\"usb\", ATTRS{idVendor}==\"$DEVICE_VENDOR\", ATTRS{idProduct}==\"$DEVICE_PRODUCT\" RUN+=\"/usr/local/sbin/enable-wakeup \$env{DEVPATH}\" "

  # add udev rule for current device
  echo "# ${DEVICE_NAME}" >> $UDEV_FILE
  echo ${DEVICE_RULE} >> $UDEV_FILE
done

# if at least one device has been selected, display notification
TITLE="USB resume enabled"
TEXT="Your USB devices are resume enabled.\nTo finalize configuration you have to do one of these actions :\n- replug USB devices\n- reboot the computer"
[ ${#ARR_CHOICE[@]} -gt 0 ] && notify-send --icon=media-eject $TITLE $TEXT

6. Setup the Devices

Everything is now ready to setup your USB devices to be able to resume your computer.

We now have to lauch the devices selection script :

# sudo /usr/local/sbin/select-resume-devices

The window will list all the USB devices available on your computer, excluding hubs. You can select as many devices as you want.

After devices selection and validation, the udev rules will be declared in /etc/udev/rules.d/90-hid-wakeup-enable.rules.

/etc/udev/rules.d/90-hid-wakeup-enable.rules

# udev rule for USB wake-up of selected devices
#
# Elan Microelectronics Corp. 3D Optical Mouse
SUBSYSTEM=="usb", ATTRS{idVendor}=="04f3", ATTRS{idProduct}=="0230" RUN+="/usr/local/sbin/enable-wakeup $env{DEVPATH}"

For the rules to become operationnal, you now need to either reboot your computer or unplug / replug your USB devices

So, just unplug and replug one of the selected devices.

You will get a message in syslog saying that configuration has been appplied.

# cat /var/log/syslog | grep logger
...
May 17 14:49:10 xxxxxxx logger: USB device 04f3:0230 - Description : Elan Microelectronics Corp. 3D Optical Mouse
May 17 14:49:10 xxxxxxx logger: USB device 04f3:0230 - SysFS path : /sys/devices/pci0000:00/0000:00:1d.0/usb5/5-1/5-1:1.0
May 17 14:49:10 xxxxxxx logger: USB device 04f3:0230 - Device is enabled to handle suspend/resume

You can now suspend your computer and resume it from your USB connected device with a simple key press, a mouse button press, your remote power button, ...

Enjoy and save time !

Signature Technoblog

This article is published "as is", without any warranty that it will work for your specific need.
If you think this article needs some complement, or simply if you think it saved you lots of time & trouble,
just let me know at This email address is being protected from spambots. You need JavaScript enabled to view it.. Cheers !

icon linux icon debian icon apache icon mysql icon php icon piwik icon googleplus