Skip to content

Instantly share code, notes, and snippets.

@costis-t
Created October 9, 2019 14:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save costis-t/211faa370ae32d17ee491b5fcf56de44 to your computer and use it in GitHub Desktop.
Save costis-t/211faa370ae32d17ee491b5fcf56de44 to your computer and use it in GitHub Desktop.
#!/bin/bash
# This script attempts to read /sys/devices/ and identify usb ports and devices
# that can be toggled to enable wakeup from sleep.
#
# Version: 2.0
# Date written: August 20, 2012
#
# Copyright (C) 2012 danomac @ gentoo forums
# Gentoo forum thread: http://forums.gentoo.org/viewtopic-t-933934.html
# The forum thread has instructions and examples on on how to use.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
# Return code documentation
#
# 1: No parameter / unknown parameter specified
# 2: Multiple actions requested, can only process one at a time
# 3: Effective user ID not root (root is required)
#
# 7: No action requested
# 8: Quiet and verbose requested at the same time! Use one or the other.
# 9: Kernel Dmesg` option requested with action other than list
#
# Internal errors:
#
# 10: toggleall() - first parameter missing (internal error)
# 11: toggleusbdevice() - first parameter not specified (internal error)
# 12: toggleusbdevice() - second parameter not specified (internal error)
# 13: toggleusbdevice() - third parameter needed but not specified! (internal error)
function listusbwakeup () {
# If quiet option is set, notify user it's being ignored
if $QUIET; then echo "Quiet option set; ignoring..."; echo ""; fi
# Initialize counter (to total items found later)
COUNT=0
echo "Listing USB hubs/devices and their wakeup status..."
# If verbose output is requested, switch to full detail view
if $VERBOSE
then
echo "
USB ID :: Device* :: Status
Device full path
Vendor :: Device Description
---------------------------------"
else
echo "
USB ID :: Device* :: Status :: Device Description
----------------------------------------------------"
fi
# Search for all wakeup files under /sys/devices
for i in `find /sys/devices -type f -name wakeup`;
do
# Extract the directory name where wakeup file resides
DEVDIRNAME=`dirname $i`
# Extract the actual device name (remove the power directory)
DEVNAME=`dirname $DEVDIRNAME`
# Now remove the directory path, leaving only the device's proper name (usb4, 4-1, etc)
DEVPROPERNAME=`basename $DEVNAME`
# Check for a product name. If none is found we most likely aren't interested in it.
if [ -e $DEVDIRNAME/../product ]
then
# We found one! Find other relevant information, if none found use a placeholder.
if [ -e $DEVDIRNAME/../product ]; then PRODUCT=`cat $DEVDIRNAME/../product`; else PRODUCT="No product name"; fi
if [ -e $DEVDIRNAME/../manufacturer ]; then VENDOR=`cat $DEVDIRNAME/../manufacturer`; else VENDOR="No vendor name"; fi
if [ -e $DEVDIRNAME/../idVendor ]; then IDVENDOR=`cat $DEVDIRNAME/../idVendor`; else IDVENDOR="No VendorID"; fi
if [ -e $DEVDIRNAME/../idProduct ]; then IDPRODUCT=`cat $DEVDIRNAME/../idProduct`; else IDPRODUCT="No Product ID"; fi
# If verbose output is selected, switch to full detail view
if $VERBOSE
then
echo "$IDVENDOR:$IDPRODUCT :: $DEVPROPERNAME :: `cat $i`"
echo " $DEVNAME"
echo " $VENDOR :: $PRODUCT"
echo ""
else
echo "$IDVENDOR:$IDPRODUCT :: $DEVPROPERNAME :: `cat $i` :: $PRODUCT"
fi
# Increment our totals counter
COUNT=`expr $COUNT + 1`
fi
done;
# Need to format the output differently for normal mode by adding an extra blank line
if ! $VERBOSE; then echo ""; fi
echo "*Use the Device column to identify hubs/devices to be toggled."
# If there's no results indiciate so
if [ $COUNT -eq 0 ]
then
echo ""
echo " NO USB hubs/devices found, or none are toggle-able!"
else
# Hey, we have results, show the total found
echo ""
echo "$COUNT USB hubs/devices listed."
fi
# If the dmesg hints were requested, show them
if $KERNELDMESG
then
echo "
Hints from dmesg (use this to try to identify your keyboard and mouse, you
may need to reboot to see anything relevant, see help for more info):
"
dmesg | grep ^input
fi
}
function toggleusbdevice () {
# toggleusbdevice (enabledevice:boolean, enableall:boolean, devname:string)
# First parameter is boolean. True to enable device; False to
# disable device.
# Second parameter is boolean. True to enable all relevant devices found,
# false to enable one device, specified in parameter 3.
# Third parameter is the name of the device from the Device column of list
# output
# Make sure both parameters are passed to this function!
if [ -z "$1" ]; then exit 11; fi
if [ -z "$2" ]; then exit 12; fi
# If specifying a single device to be changed, make sure parameter 3
# exists!
if ! $2
then
if [ -z "$3" ]; then exit 13; fi
fi
# Verbose detail is used throughout this function. Echo extra detail if
# requested
if $VERBOSE; then echo "Starting to parse wakeup devices found..."; fi
# Search for all wakeup files under /sys/devices
for i in `find /sys/devices -type f -name wakeup`;
do
# Extract the directory name where wakeup file resides
DEVDIRNAME=`dirname $i`
# Extract the actual device name (remove the power directory)
DEVNAME=`dirname $DEVDIRNAME`
# Now remove the directory path, leaving only the device's proper name (usb4, 4-1, etc)
DEVPROPERNAME=`basename $DEVNAME`
# Are we updating one specific device or all of them?
if ! $2
then
# Update individual device
if $VERBOSE; then echo "Is this device ($DEVPROPERNAME) the same as the requested device ($3)?"; fi
# Check for a product name. If none is found we most likely aren't interested in it.
if [ "$DEVPROPERNAME" == "$3" ]
then
if $VERBOSE; then echo "YES! Attempting to change."; fi
if $1
then
if $VERBOSE || ! $QUIET; then echo "Attempting to enable device ($DEVPROPERNAME)..."; fi
# Enable device
echo "enabled" > $i
if $VERBOSE || ! $QUIET
then
if [ $? -ne 0 ]; then echo "Failed."; else echo "Success!"; fi
fi
exit 0
else
# Disable device
if $VERBOSE || ! $QUIET; then echo "Attempting to disable device ($DEVPROPERNAME)..."; fi
# Enable device
echo "disabled" > $i
if $VERBOSE || ! $QUIET
then
if [ $? -ne 0 ]; then echo "Failed."; else echo "Success!"; fi
fi
exit 0
fi
else
if $VERBOSE; then echo "...no."; fi
fi
else
# Update all devices
if $VERBOSE; then echo "Does this device ($DEVPROPERNAME) look like a USB hub/device?"; fi
# Check for a product name. If none is found we most likely aren't interested in it.
if [ -e $DEVDIRNAME/../product ]
then
# If verbose output is selected, switch to full detail view
if $VERBOSE; then echo "YES!"; fi
if $1
then
if $VERBOSE || ! $QUIET; then echo "Attempting to enable device ($DEVPROPERNAME)..."; fi
# Enable device
echo "enabled" > $i
if $VERBOSE || ! $QUIET
then
if [ $? -ne 0 ]; then echo "Failed."; else echo "Success!"; fi
fi
else
# Disable device
if $VERBOSE || ! $QUIET; then echo "Attempting to disable device ($DEVPROPERNAME)..."; fi
# Enable device
echo "disabled" > $i
if $VERBOSE || ! $QUIET
then
if [ $? -ne 0 ]; then echo "Failed."; else echo "Success!"; fi
fi
fi
else
if $VERBOSE; then echo "...no."; fi
fi
fi
done;
# If updating only one device and we get this far it wasn't found.
if ! $2; then echo "Device not found."; fi
}
function showhelp () {
# If quiet option is passed notify user it's being ignored
if $QUIET; then echo "Quiet option set; ignoring..."; fi
echo "
$0: a script that lists and toggles wakeup on usb hubs
Usage: $0 [options] [action] [parameters]
Actions:
-l : list available usb hubs/devices that can be toggled and their
current status (enabled/disabled)
-a : enable wakeup on all discovered usb hubs/devices
Use caution with this; it's better to identify individual
hubs/devices rather than enable them all. You might find
your computer woke itself unintentionally.
-x : disable wakeup on all discovered usb hubs/devices
-e : enable wakeup on specific hub/device (requires parameter,
see below.)
-d : disable wakeup on specific hub/device (requires parameter,
see below.)
-h : this screen
Options:
-q : Quiet mode for all but help and list actions
-v : Enable verbose output
-k : Try to show hints from dmesg (list action only)
This dmesg option will show lines starting with input
in order to try to identify devices.
It is usually presented as /sys/devices/*/usb?/*/input/input?.
If nothing useful is displayed, try rebooting as relevant
information can be out of the buffer if the PC has been on for
some time.
Parameters:
Both -e and -d actions require a parameter to search for, use -l to list.
The parameter needed is in the Device column.
Sample output of $0 -l:
Listing USB devices and their wakeup status...
USB ID :: Device* :: Status :: Device Description
----------------------------------------------------
1d6b:0001 :: usb4 :: enabled :: UHCI Host Controller
046d:c508 :: 4-1 :: enabled :: USB Receiver
046d:c221 :: 4-2.1 :: enabled :: Gaming Keyboard
The identifier needed for the parameter is usb4, 4-1, or 4-2.1.
No arguments will show this screen.
"
}
# Start of "main" routine
# Make sure user is root (script will not work as user)
if [ $EUID -ne 0 ]; then echo "This script must be run as root."; exit 3; fi
# Initialize variables:
# QUIET=quiet mode (no echo) - default false. Toggled with -q option.
# KERNELDMESG=dmesg list option in list mode. Default false, toggled with
# -k option
# ACTION=default 0; used to make sure more than one action are not
# specified at the same time.
# VERBOSE=default false. Extra detail in some actions.
QUIET=false
KERNELDMESG=false
VERBOSE=false
ACTION=0
# Show help if no arguments provided at all
if [ $# -eq 0 ]; then showhelp; exit 1; fi
# Process arguments passed, setting environment appropriately.
while getopts “hkqvlaxe:d:” OPTION
do
case $OPTION in
h) # Help action
# Make sure multiple actions are not chosen.
if [ $ACTION -ne 0 ]; then echo "You can only declare one action at a time."; echo ""; showhelp; exit 2; fi
ACTION=1
;;
q) # Quiet option
QUIET=true
;;
k) # Kernel dmesg in list mode option
KERNELDMESG=true
;;
v) # Verbose option
VERBOSE=true
;;
l) # List action
# Make sure multiple actions are not chosen.
if [ $ACTION -ne 0 ]; then echo "You can only declare one action at a time."; echo ""; showhelp; exit 2; fi
ACTION=2
;;
a) # Enable all USB hubs/devices action
# Make sure multiple actions are not chosen.
if [ $ACTION -ne 0 ]; then echo "You can only declare one action at a time."; echo ""; showhelp; exit 2; fi
ACTION=3
;;
x) # Disable all USB hubs/devices action
# Make sure multiple actions are not chosen.
if [ $ACTION -ne 0 ]; then echo "You can only declare one action at a time."; echo ""; showhelp; exit 2; fi
ACTION=4
;;
e) # Enable specific hub/device via find command action
# Make sure multiple actions are not chosen.
if [ $ACTION -ne 0 ]; then echo "You can only declare one action at a time."; echo ""; showhelp; exit 2; fi
ACTION=5
# Save arguments passed for later
ENABLEUSB=$OPTARG
;;
d) # Disable specific hub/device via find command action
# Make sure multiple actions are not chosen.
if [ $ACTION -ne 0 ]; then echo "You can only declare one action at a time."; echo ""; showhelp; exit 2; fi
ACTION=6
# Save arguments passed for later
DISABLEUSB=$OPTARG
;;
?) # Unknown parameter
showhelp
exit 1
;;
esac
done
# Some sanity checks
# Quiet and verbose can't be set at the same time
if $QUIET && $VERBOSE; then echo "You can't specify quiet (-q) and verbose (-v) at the same time."; echo ""; exit 8; fi
# Kernel DMESG can only be used with the list action
if $KERNELDMESG && (( $ACTION != 2 )); then echo "The hints from dmesg option (-k) can only be used with the list (-l) action."; echo ""; exit 9; fi
# Make sure an action was selected!
if (($ACTION == 0 )); then echo "You haven't requested an action!"; exit 7; fi
# We seem to be safe, so actually perform the request
case $ACTION in
1) # help action
showhelp
exit
;;
2) # list action
listusbwakeup
exit
;;
3) # enable all devices
toggleusbdevice true true
exit
;;
4) # disable all devices
toggleusbdevice false true
exit
;;
5) # enable one device
toggleusbdevice true false $ENABLEUSB
exit
;;
6) # disable one device
toggleusbdevice false false $DISABLEUSB
exit
;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment