モブ沢工房

プログラミングとかLinux関連(特にOSSのグラフィックツール関連)とかレトロゲームとか3Dプリンタやら日曜大工等、色々。

Ubuntu 14.04におけるUSB3.0のサスペンド機能不全問題について : やっつけ的解決策

さて、以前から問題にしていたUbuntu 14.04におけるサスペンド機能不全問題。 もしかしてオイラのところだけで起きているのではないか…とすら思えるのですが*1

なお、NEC(現ルネサス)のUSB3.0チップを搭載するP67A-GD55では、この問題は発生していませんので、USB3.0増設カードを買うのも一興かもです。

うちの環境で確実に再現する手段は

  1. USB3.0のHDDをAsrock H77MのバックパネルのUSB3.0ポートに接続
  2. マウントする
  3. 使う
  4. アンマウントする

以後、サスペンドに入るとモニタの電源を一瞬だけ落とす感じですぐにレジュームするという現象です。なお、USB3.0のHDDをアンマウントする前にサスペンドすると何故か大丈夫というオモシロ現象まで起きているのでした。

確か12.04の時は起きていなかったと思うのですが、かなりうろ覚え…

とりあえずの対策は全てのUSBからのウェイクアップをdisableする、すなわちrootにて

echo 'disabled' > /sys/bus/pci/devices/0000:00:1d.0/power/wakeup
echo 'disabled' > /sys/bus/pci/devices/0000:00:1a.0/power/wakeup
echo 'disabled' > /sys/bus/pci/devices/0000:00:14.0/power/wakeup

というものでした。*2

そこでもうキーボードなどからのレジュームは諦め、daemonを作って常にdisableしてやろうかなと思ったのですがなんか迂遠な気がするし、不慣れな自分ではトライ&エラーが必須で面倒くさい。

そこで、ハッとひらめきました。

/etc/pm/sleep.d/に自分専用の設定を作り、そこでサスペンド直前にdisableしてしまえばお手軽確実なのでは?

と。

USBのウェイクアップを停止するのは、既に専用スクリプトは組んであるのでそれを呼び出すだけでいい。

そして専用スクリプトも多少手を加えて、既にdisabledであればそれ以上echoしない(別に問題はないと思うのだけど、気持ち悪いので)ように改造したのが、以下のものです。

change_usb_wakeup.sh

#!/bin/bash

cmdstr="disabled"

while [ "$1" != "" ];do

    case $1 in
    -e | --enable)
        cmdstr="enabled"
        ;;
    -d | --disable)
        cmdstr="disabled"
        ;;
    * )
        echo $1 is unrecognized option
        ;;
    esac
shift 1
done


function exec_disable
{
    local syspath=/sys/bus/pci/devices/0000\:00\:${1}.0/power/wakeup
    local state=`cat $syspath`

    if [ "$state" != "$cmdstr" ];then
        echo "echo '${cmdstr}' >  $syspath"
        echo "${cmdstr}" >  $syspath
    else
        echo $syspath has been already set as $cmdstr
    fi

}

exec_disable 1d
exec_disable 1a
exec_disable 14

これを、/etc/pm/sleep.d/99-disable-usb-wakeup とする、以下のファイルにから呼び出します

#!/bin/sh

case "$1" in
    suspend)
        /usr/local/scripts/change_usb_wakeup.sh
        ;;
    resume)
        ;;
esac

当然ながらchange_usb_wakeup.shのパスは環境に応じて変更してくださいw

これで電源ボタンからしかレジュームできなくなりましたが、まぁ、いいかぁと。

*1:一応報告はしておきました

*2:デバイスパスはH77Mのものであり、他の環境だと違うかもです