reload_network_device: Generalize for non-WiFi

Adapt the reload_wifi script to work with other network devices
other than wireless-LAN.  Also add the capability of handling
USB devices in addition to PCI.  Also "rmmod" the device before
restarting in the hopes of having the reload process work more
smoothly.

BUG=chromium:348610
TEST="reload_network_device eth0; reload network_device wlan0"

Change-Id: I1158fe9a564760409b41c64ac919aac29a70cbe8
Reviewed-on: https://chromium-review.googlesource.com/188916
Reviewed-by: mukesh agrawal <quiche@chromium.org>
Commit-Queue: Paul Stewart <pstew@chromium.org>
Tested-by: Paul Stewart <pstew@chromium.org>
diff --git a/bin/reload_network_device b/bin/reload_network_device
new file mode 100755
index 0000000..161e3b8
--- /dev/null
+++ b/bin/reload_network_device
@@ -0,0 +1,79 @@
+#!/bin/sh
+#
+# Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+#
+# UDEV event helper script that restarts a hung network device.
+
+POWER_DOWN_TIME_SECONDS=1
+WLAN_REINITIALIZE_TIME_SECONDS=5
+
+set -e
+
+error () {
+  logger -t $0 "Error: $1"
+  exit 1
+}
+
+if [ -n "${1}" ] ; then
+  eval $(udevadm info --query=property --path="/sys/class/net/${1}" |
+         egrep '^(DEVPATH|DEVTYPE|ID_BUS|INTERFACE|SUBSYSTEM)')
+  EVENT=device_hang
+fi
+
+if [ "${SUBSYSTEM}" != "net" -o \
+     "${EVENT}" != "device_hang" -o \
+     -z "${DEVPATH}" ] ; then
+  exit 0
+fi
+
+logger -t $0 "Restarting network interface ${INTERFACE}"
+
+# The DEVPATH for a network interface should look something like:
+#   /devices/pci0000:00/0000:00:1c.0/0000:01:00.0/net/wlan0
+if [ $(basename $(dirname "${DEVPATH}")) != 'net' ] ; then
+  error "Device path for ${INTERFACE} (${DEVPATH}) is invalid."
+fi
+
+device_path=$(readlink -f "/sys${DEVPATH}/../..")
+module_name=$(basename $(readlink -f "/sys${DEVPATH}/device/driver/module"))
+
+rmmod "${module_name}"
+
+if [ "${ID_BUS}" = "pci" ] ; then
+  device_remove_path="${device_path}/remove"
+  bus_rescan_path=$(readlink -f  "${device_path}/../rescan")
+
+  if [ ! -e "${device_remove_path}" ] ; then
+    error "Device remove path ${device_remove_path} does not exist"
+  fi
+
+  if [ ! -e "${bus_rescan_path}" ] ; then
+    error "Bus rescan path ${bus_rescan_path} does not exist"
+  fi
+
+  echo 1 > "${device_remove_path}"
+  if [ "${DEVTYPE}" = "wlan" ] ; then
+    ectool wireless 0xe  # Disable wireless lan.
+    ectool wireless 0x6  # Power down wireless lan.
+  fi
+
+  sleep ${POWER_DOWN_TIME_SECONDS}
+
+  if [ "${DEVTYPE}" = "wlan" ] ; then
+    ectool wireless 0xe  # Power up wireless lan.
+    ectool wireless 0xf  # Enable wireless lan.
+
+    sleep ${WLAN_REINITIALIZE_TIME_SECONDS}
+  fi
+
+  echo 1 > "${bus_rescan_path}"
+elif [ "${ID_BUS}" = "usb" ] ; then
+  device_authorize_path=$(readlink -f "${device_path}/../authorized")
+  echo 0 > "${device_authorize_path}"
+  sleep ${POWER_DOWN_TIME_SECONDS}
+  echo 1 > "${device_authorize_path}"
+else
+  error "Bus type ${ID_BUS} is unknown"
+fi
diff --git a/bin/reload_wifi b/bin/reload_wifi
deleted file mode 100755
index 537e6e3..0000000
--- a/bin/reload_wifi
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-#
-# UDEV event helper script that restarts a hung WiFi device.
-
-POWER_DOWN_TIME_SECONDS=1
-DEVICE_REINITIALIZE_TIME_SECONDS=5
-
-set -e
-
-error () {
-  logger -t $0 "Error: $1"
-  exit 1
-}
-
-if [ -n "${1}" ] ; then
-  eval $(udevadm info --query=property --path="/sys/class/net/${1}" |
-         egrep '^(DEVPATH|DEVTYPE|SUBSYSTEM|INTERFACE)')
-  EVENT=device_hang
-fi
-
-if [ "${SUBSYSTEM}" != "net" -o
-     "${DEVTYPE}" != "wlan" -o
-     "${EVENT}" != "device_hang" -o
-     -z "${DEVPATH}" ] ; then
-  exit 0
-fi
-
-logger -t $0 "Restarting wireless lan network interface ${INTERFACE}"
-
-# The DEVPATH for a wlan network interface should look something like:
-#   /devices/pci0000:00/0000:00:1c.0/0000:01:00.0/net/wlan0
-if [ $(basename $(dirname "${DEVPATH}")) != 'net' ] ; then
-  error "Device path for ${INTERFACE} (${DEVPATH}) is invalid."
-fi
-
-device_path=$(dirname $(dirname "/sys${DEVPATH}"))
-device_remove_path="${device_path}/remove"
-bus_rescan_path=$(dirname "${device_path}")/rescan
-
-if [ ! -e "${device_remove_path}" ] ; then
-  error "Device remove path ${device_remove_path} does not exist"
-fi
-
-if [ ! -e "${bus_rescan_path}" ] ; then
-  error "Bus rescan path ${bus_rescan_path} does not exist"
-fi
-
-echo 1 > "${device_remove_path}"
-ectool wireless 0xe  # Disable wireless lan.
-ectool wireless 0x6  # Power down wireless lan.
-
-sleep ${POWER_DOWN_TIME_SECONDS}
-
-ectool wireless 0xe  # Power up wireless lan.
-ectool wireless 0xf  # Enable wireless lan.
-
-sleep ${DEVICE_REINITIALIZE_TIME_SECONDS}
-
-echo 1 > "${bus_rescan_path}"