Home | History | Annotate | Download | only in bin
      1 #!/bin/sh
      2 #
      3 #
      4 # Copyright (C) 2014 The Android Open Source Project
      5 #
      6 # Licensed under the Apache License, Version 2.0 (the "License");
      7 # you may not use this file except in compliance with the License.
      8 # You may obtain a copy of the License at
      9 #
     10 #      http://www.apache.org/licenses/LICENSE-2.0
     11 #
     12 # Unless required by applicable law or agreed to in writing, software
     13 # distributed under the License is distributed on an "AS IS" BASIS,
     14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     15 # See the License for the specific language governing permissions and
     16 # limitations under the License.
     17 #
     18 #
     19 # UDEV event helper script that restarts a hung network device.
     20 
     21 POWER_DOWN_TIME_SECONDS=1
     22 WLAN_POWER_UP_TIME_SECONDS=1
     23 WLAN_REINITIALIZE_TIME_SECONDS=5
     24 
     25 set -e
     26 
     27 error () {
     28   logger -t $0 "Error: $1"
     29   exit 1
     30 }
     31 
     32 if [ -n "${1}" ] ; then
     33   eval $(udevadm info --query=property --path="/sys/class/net/${1}" |
     34          egrep '^(DEVPATH|DEVTYPE|ID_BUS|INTERFACE|SUBSYSTEM)')
     35   EVENT=device_hang
     36 fi
     37 
     38 if [ "${SUBSYSTEM}" != "net" -o \
     39      "${EVENT}" != "device_hang" -o \
     40      -z "${DEVPATH}" ] ; then
     41   exit 0
     42 fi
     43 
     44 logger -t $0 "Restarting network interface ${INTERFACE}"
     45 
     46 # The DEVPATH for a network interface should look something like:
     47 #   /devices/pci0000:00/0000:00:1c.0/0000:01:00.0/net/wlan0
     48 if [ $(basename $(dirname "${DEVPATH}")) != 'net' ] ; then
     49   error "Device path for ${INTERFACE} (${DEVPATH}) is invalid."
     50 fi
     51 
     52 device_path=$(readlink -f "/sys${DEVPATH}/../..")
     53 module_name=$(basename $(readlink -f "/sys${DEVPATH}/device/driver/module"))
     54 
     55 rmmod "${module_name}"
     56 
     57 if [ "${ID_BUS}" = "pci" ] ; then
     58   device_remove_path="${device_path}/remove"
     59   bus_rescan_path=$(readlink -f  "${device_path}/../rescan")
     60 
     61   if [ ! -e "${device_remove_path}" ] ; then
     62     error "Device remove path ${device_remove_path} does not exist"
     63   fi
     64 
     65   if [ ! -e "${bus_rescan_path}" ] ; then
     66     error "Bus rescan path ${bus_rescan_path} does not exist"
     67   fi
     68 
     69   echo 1 > "${device_remove_path}"
     70   if [ "${DEVTYPE}" = "wlan" ] ; then
     71     ectool wireless 0xe  # Disable wireless lan.
     72     ectool wireless 0x6  # Power down wireless lan.
     73   fi
     74 
     75   sleep ${POWER_DOWN_TIME_SECONDS}
     76 
     77   if [ "${DEVTYPE}" = "wlan" ] ; then
     78     ectool wireless 0xe  # Power up wireless lan.
     79     sleep ${WLAN_POWER_UP_TIME_SECONDS}
     80     ectool wireless 0xf  # Enable wireless lan.
     81 
     82     sleep ${WLAN_REINITIALIZE_TIME_SECONDS}
     83   fi
     84 
     85   echo 1 > "${bus_rescan_path}"
     86 elif [ "${ID_BUS}" = "usb" ] ; then
     87   device_authorize_path=$(readlink -f "${device_path}/../authorized")
     88   echo 0 > "${device_authorize_path}"
     89   sleep ${POWER_DOWN_TIME_SECONDS}
     90   echo 1 > "${device_authorize_path}"
     91 else
     92   error "Bus type ${ID_BUS} is unknown"
     93 fi
     94