Nov21

Suspend2 on Thinkpad W510

Following my previous posts and using xhci & xhci_hcd for USB 3.0 support leads to problems when suspend to disk/ram: Some USB 3.0 devices just don’t suspend and the hibernate process will be canceled.
On thing we can do is to unbind all devices using the USB kernel modules. A list of active devices can be found as follows:

$ find /sys/bus/pci/drivers/ehci_hcd -type l | grep -v module
/sys/bus/pci/drivers/ehci_hcd/0000:00:1a.0
/sys/bus/pci/drivers/ehci_hcd/0000:00:1d.0

So we just have to unbind those devices:

echo -n 0000:00:1a.0 > /sys/bus/pci/drivers/ehci_hcd/unbind
echo -n 0000:00:1d.0 > /sys/bus/pci/drivers/ehci_hcd/unbind

Note that your USB attached devices will stop working until you re-bind them:

echo -n 0000:00:1a.0 > /sys/bus/pci/drivers/ehci_hcd/bind
echo -n 0000:00:1d.0 > /sys/bus/pci/drivers/ehci_hcd/bind

You can put the stuff together in a scriptlet to do an unbind before suspend and a re-bind on resume:

# -*- sh -*-

AddConfigHandler xhci_parse_option
AddConfigHelp "xhci_devices " "Device list to unbind/bind USB devices using xhci on suspend/resume"

xhci_unbind() {
    for device in $devices
    do
        echo -n $device > /sys/bus/pci/drivers/ehci_hcd/unbind
    done
    return 0
}

xhci_bind() {
    for device in $devices
    do
        echo -n $device > /sys/bus/pci/drivers/ehci_hcd/bind
    done
    return 0
}

xhci_parse_option() {
    case $1 in
        xhci_devices)
            devices="$*"
            return 0
            ;;

        *)
        return 1
    esac

    if [ -z "$XHCI_HOOKED" ] ; then
        AddSuspendHook 35 xhci_unbind
        AddResumeHook 35 xhci_bind
        XHCI_HOOKED=1
    fi
    return 0
}

To install the scriptlet just create a file in /etc/hibernate/scriptlets.d and define a device list e.g. in /etc/hibernate/common.conf:

$ cat /etc/hibernate/common.conf
# ...
xhci_devices 0000:00:1a.0 0000:00:1d.0
# ...

Unforunately the aproach above did not work. Some USB devices seems to be still active and refused to suspend. Since I do not really have any USB 3.0 device, I decided to disable USB 3.0 until I get the above approach working:

Device Drivers
    [*] USB support
        []  xHCI HCD (USB 3.0)

With this kernel configuration, we get suspend to disk working. But resuming the systems brings another problem with NVidia drivers 260.19.21 (64bit): The resumed system was either extremely slow or we just got a white screen. In both cases, restarting X fixed the problem but this is obviously not a solution. I found some information about a bug using NVidia’s TwinView together with hibernation. Following the proposed workaround, I enabled the NvAGP driver option:

$ cat /etc/X11/xorg.conf.d/nvidia.conf
Section "Device"
    Identifier  "Device0"
    Driver  "nvidia"
    VendorName  "NVIDIA Corporation"
    BoardName   "Nvidia Quadro FX880M"
    Option  "AddARGBGLXVisuals" "true"
    Option  "NoLogo" "true"

    # Enable brightness control
    Option      "RegistryDwords" "EnableBrightnessControl=1"

    # Workaround: Enabling twinview breaks suspend
    Option  "NvAGP" "1"

EndSection

And prevent the kernel from loading intel_agp module. Either by adding the following line to the modprobe blacklist:

$ cat /etc/modprobe.d/blacklist.conf | grep intel_agp
blacklist intel_agp

Or you just make sure that the modules is neither build-in nor compiled as module in the current kernel configuration.

Leave a Reply

You must be logged in to post a comment.