power: powerd_suspend: Issue hcitool command only on Intel BT platforms

Apparently, the Marvell bluetooth controller *sometimes* fails to
respond to the command used to enable / disable mode change HCI event.
The issue is rarely reproduced at random. So:

* Issue the command only on platforms that have Intel BT controllers.
* Timeout hcitool command at 2 seconds in order to ensure that a
  bad controller cannot take forever to respond. The timeout of 2 secs
  is taken from HCI_CMD_TIMEOUT in kernel.

BUG=chromium:803272
TEST=Suspend / resume on Kevin does not issue the hcitool command.
     Suspend resume on a Soraka issues the hcitool command.
     Faking a hang (using sleep command instead of hcitool) kills the
     command and logs a message)

Change-Id: I399f2ca794e135b703cbc0d46d15039649e30ab4
Reviewed-on: https://chromium-review.googlesource.com/915341
Reviewed-by: Dan Erat <derat@chromium.org>
Tested-by: Rajat Jain <rajatja@chromium.org>
Commit-Queue: Rajat Jain <rajatja@chromium.org>
Trybot-Ready: Rajat Jain <rajatja@chromium.org>
diff --git a/power_manager/powerd/powerd_suspend b/power_manager/powerd/powerd_suspend
index ab01c68..0af990c 100755
--- a/power_manager/powerd/powerd_suspend
+++ b/power_manager/powerd/powerd_suspend
@@ -236,12 +236,31 @@
   local file
   for file in /sys/class/bluetooth/hci[0-9]; do
     local hcidev="$(basename "${file}")"
+    local bt_vendor=""
+    local retval=""
+    local usb_path="$(readlink ${file})"
+    usb_path="/sys/class/bluetooth/${usb_path%/bluetooth/*}/.."
+    bt_vendor="$(cat ${usb_path}/idVendor)"
+
+    # Don't do anything for non-Intel controllers. Some of them may
+    # not support it well (See http://crbug.com/803272)
+    if [ "${bt_vendor}" != "8087" ]; then
+      log_msg "Skipping $1 BT HCI mode change event on non-Intel BT"
+      continue
+    fi
     if [ "$1" = "disable" ]; then
-      echo "Disabling Bluetooth HCI mode change event before suspend"
-      hcitool -i "${hcidev}" cmd 03 01 ff ff f7 ff ff ff ff ff
+      log_msg "Disabling Bluetooth HCI mode change event before suspend"
+      timeout -k 2 2 hcitool -i "${hcidev}" cmd 03 01 ff ff f7 ff ff ff ff ff
     elif [ "$1" = "enable" ]; then
-      echo "Enabling Bluetooth HCI mode change event after resume"
-      hcitool -i "${hcidev}" cmd 03 01 ff ff ff ff ff ff ff ff
+      log_msg "Enabling Bluetooth HCI mode change event after resume"
+      timeout -k 2 2 hcitool -i "${hcidev}" cmd 03 01 ff ff ff ff ff ff ff ff
+    fi
+    retval=$?
+    # retval = 124/137 indicates timedout, please refer to timeout man page
+    if [ ${retval} -eq 137 ] || [ ${retval} -eq 124 ]; then
+      log_msg "hcitool command timed out (Killed)"
+    elif [ ${retval} -ne 0 ]; then
+      log_msg "hcitool failed with exit status ${retval}"
     fi
   done
 }