From 8dd91340660a14c55d12372a3e9a767863b7f316 Mon Sep 17 00:00:00 2001 From: Keng-Yu Lin <keng-yu....@canonical.com> Date: Thu, 24 Feb 2011 13:59:14 +0800 Subject: [PATCH] Add the quirk support for stoping/restarting bluetooth service
It is found that the bluetooth modules with USB VID/PIDs [0a5c:219c] [0a5c:21bc] and [413c:8187] are causing random S4 hangs on various laptops with SandyBridge chipset. The hangs can be observed by repeating hibernate/resume in a 250 iterations. The successful cycles number before the hang is usually ranged in tens, though it varies on different types of laptops. This patch added a parameter for the use as "pm-hibernate --quirk-bluetooth-service-off" and a couple of USB ID quirks I found with this S4 problem. Signed-off-by: Keng-Yu Lin <keng-yu....@canonical.com> --- pm/sleep.d/44bluetooth-known-quirk | 34 +++++++++++++++++++++++++++++ pm/sleep.d/45bluetooth-service | 41 ++++++++++++++++++++++++++++++++++++ pm/sleep.d/Makefile.am | 2 + 3 files changed, 77 insertions(+), 0 deletions(-) create mode 100755 pm/sleep.d/44bluetooth-known-quirk create mode 100755 pm/sleep.d/45bluetooth-service diff --git a/pm/sleep.d/44bluetooth-known-quirk b/pm/sleep.d/44bluetooth-known-quirk new file mode 100755 index 0000000..7241ec8 --- /dev/null +++ b/pm/sleep.d/44bluetooth-known-quirk @@ -0,0 +1,34 @@ +#!/bin/bash + +. "${PM_FUNCTIONS}" + +quirks="0a5c:219c 0a5c:21bc 413c:8187" + +btusbget() { + local dev usb + usb="/sys/bus/usb/devices" + for dev in "$usb"/*; do + [[ -f "${dev}/bDeviceClass" ]] || continue + [[ "$(cat "${dev}/bDeviceClass")" = "e0" ]] || continue # Wireless + [[ -f "${dev}/bDeviceProtocol" ]] || continue + [[ "$(cat "${dev}/bDeviceProtocol")" = "01" ]] || continue # Bluetooth + case $1 in + vendor) echo "$(cat "${dev}/idVendor")" ;; + device) echo "$(cat "${dev}/idProduct")" ;; + esac + break + done +} + +case "$1" in + hibernate|suspend) + # known bluetooth devices needing to stop bluetoothd + for usbid in $quirks; do + if [ "$(btusbget vendor):$(btusbget device)" == "$usbid" ] ; then + add_parameters --quirk-bluetooth-service-off + fi + done + ;; + thaw|resume) + ;; +esac diff --git a/pm/sleep.d/45bluetooth-service b/pm/sleep.d/45bluetooth-service new file mode 100755 index 0000000..969ca86 --- /dev/null +++ b/pm/sleep.d/45bluetooth-service @@ -0,0 +1,41 @@ +#!/bin/bash + +. "${PM_FUNCTIONS}" + +for opt in $PM_CMDLINE; do + case "${opt##--quirk-}" in # just quirks, please + bluetooth-service-off) QUIRK_BLUETOOTH_SERVICE_OFF="true" ;; + bluetooth-none) QUIRK_BLUETOOTH_NONE="true" ;; + *) continue ;; + esac +done + +quirk() { is_set "$1" && [ -z $QUIRK_BLUETOOTH_NONE ]; } + +suspend_bluetooth_service() +{ + quirk "${QUIRK_BLUETOOTH_SERVICE_OFF}" && stopservice bluetooth +} + +resume_bluetooth_service() +{ + quirk "${QUIRK_BLUETOOTH_SERVICE_OFF}" && restartservice bluetooth +} + +help() { + echo # first echo makes it look nicer. + echo "Bluetooth quirk handler options:" + echo + echo " --quirk-bluetooth-service-off" + echo " --quirk-bluetooth-none" +} + +case "$1" in + hibernate|suspend) + suspend_bluetooth_service + ;; + thaw|resume) + resume_bluetooth_service + ;; + help) help ;; +esac diff --git a/pm/sleep.d/Makefile.am b/pm/sleep.d/Makefile.am index 2350825..88df79c 100644 --- a/pm/sleep.d/Makefile.am +++ b/pm/sleep.d/Makefile.am @@ -4,6 +4,8 @@ sleep_SCRIPTS = \ 00logging \ 00powersave \ 01grub \ + 44bluetooth-known-quirk \ + 45bluetooth-service \ 49bluetooth \ 55NetworkManager \ 75modules \ -- 1.7.1