#! /bin/sh
# 
# Laptop mode tools module: usb-autosuspend.
#

blacklisted() {
	for usbid in $AUTOSUSPEND_USBID_BLACKLIST; do
		if ! echo $usbid | grep -q ':'; then
			log "MSG" "WARNING: Invalid entry \"$usbid\" in AUTOSUSPEND_USBID_BLACKLIST."
		fi
		vendor=$(echo $usbid | cut -d: -f1)
		product=$(echo $usbid | cut -d: -f2)
		grep -qi $vendor $1/idVendor 2>/dev/null\
		 && grep -qi $product $1/idProduct 2>/dev/null\
		 && return 0
	done
	return 1
}

# Check whether the USB driver type is blacklisted
blacklisted_by_type() {
	device=$1
	device_base=`basename $device`
	for driver_type in $AUTOSUSPEND_USBTYPE_BLACKLIST; do
		if grep -q DRIVER=$driver_type $device/uevent; then
			return 0
		fi
		# Check child devices as well.  The actual driver type is
		# listed in a child device, not the top-level device.
		for subdevice in $device/$device_base*; do
			if [ -f $subdevice/uevent ]; then
				if grep -q DRIVER=$driver_type\
				    $subdevice/uevent; then
					return 0
				fi
			fi
		done
	done
	return 1
}


if [ x$CONTROL_USB_AUTOSUSPEND = x1 ] || [ x$ENABLE_AUTO_MODULES = x1 -a x$CONTROL_USB_AUTOSUSPEND = xauto ]; then
    if [ $ON_AC -eq 1 ]; then
        if [ "$ACTIVATE" -eq 1 ]; then
            SUSPEND_USB_DEVICES="$LM_AC_SUSPEND_USB"
        else
            SUSPEND_USB_DEVICES="$NOLM_AC_SUSPEND_USB"
        fi
    else
        SUSPEND_USB_DEVICES="$BATT_SUSPEND_USB"
    fi

    if [ -d /sys/bus/usb/devices ]; then
	if [ "$DEVICES" != "" ]; then
		# If a list of devices has been provided, operate on only the
		# listed USB devices.
		DEVICE_LIST=""
		for DEVICE in $DEVICES; do
			DEVICE_LIST="$DEVICE_LIST $DEVICE"
		done
	else
		# If no list was provided, operate on all USB devices
		DEVICE_LIST=/sys/bus/usb/devices/*
	fi
    else
	# This will rarely happen.
	log "VERBOSE" "There are no USB devices."
    fi

    if [ x$SUSPEND_USB_DEVICES = x1 ]; then
	  if [ -f /sys/module/usbcore/parameters/autosuspend ]; then
	      echo $AUTOSUSPEND_TIMEOUT > /sys/module/usbcore/parameters/autosuspend
	      log "VERBOSE" "Enabling autosuspend mode for USBCORE Controller, with timeout $AUTOSUSPEND_TIMEOUT."
	  else
	      log "VERBOSE" "Not enabling autosuspend mode for USBCORE Controller. Not Supported"
	  fi

	  if [ "$DEVICE_LIST" != "" ]; then
	      for usb_device in $DEVICE_LIST;
	      do
		  usb_device=`basename $usb_device`;
		  if ! blacklisted /sys/bus/usb/devices/$usb_device; then
			if ! blacklisted_by_type /sys/bus/usb/devices/$usb_device; then
			  if [ -f /sys/bus/usb/devices/$usb_device/power/autosuspend ]; then
				  echo $AUTOSUSPEND_TIMEOUT > /sys/bus/usb/devices/$usb_device/power/autosuspend;
				  log "VERBOSE" "Enabling auto suspend mode for usb device $usb_device."
			  else
				  log "VERBOSE" "Not enabling auto suspend mode for usb device $usb_device"
			  fi

			  if [ -f /sys/bus/usb/devices/$usb_device/power/control ]; then
				  echo "auto" > /sys/bus/usb/devices/$usb_device/power/control;
				  log "VERBOSE" "Enabling auto power level for usb device $usb_device."
			  elif [ -f /sys/bus/usb/devices/$usb_device/power/level ]; then
				  echo "auto" > /sys/bus/usb/devices/$usb_device/power/level;
				  log "VERBOSE" "Enabling auto power level for usb device $usb_device."
			  else
				  log "VERBOSE" "Not enabling auto power level for usb device $usb_device"
			  fi
			else
			  log "VERBOSE" "Device $usb_device has blacklisted driver type, skipping auto suspend."
			fi
		  else
			  log "VERBOSE" "USB device $usbid is in the autosuspend blacklist."
		  fi
	      done
	  fi
    else
	  AUTOSUSPEND_TIMEOUT=0
	  if [ -f /sys/module/usbcore/parameters/autosuspend ]; then
	      echo $AUTOSUSPEND_TIMEOUT > /sys/module/usbcore/parameters/autosuspend
	      log "VERBOSE" "Disabling autosuspend mode for USBCORE Controller, with timeout $AUTOSUSPEND_TIMEOUT."
	  else
	      log "VERBOSE" "Not disabling autosuspend mode for USBCORE Controller. Not Supported"
	  fi

	  if [ "$DEVICE_LIST" != "" ]; then
	      for usb_device in $DEVICE_LIST;
	      do
		  usb_device=`basename $usb_device`;
		  if [ -f /sys/bus/usb/devices/$usb_device/power/autosuspend ]; then
		      echo $AUTOSUSPEND_TIMEOUT > /sys/bus/usb/devices/$usb_device/power/autosuspend;
		      log "VERBOSE" "Disabling auto suspend mode for usb device $usb_device."
		  else
		      log "VERBOSE" "Not disabling auto suspend mode for usb device $usb_device"
		  fi

		  if [ -f /sys/bus/usb/devices/$usb_device/power/control ]; then
		      echo "on" > /sys/bus/usb/devices/$usb_device/power/control;
		      log "VERBOSE" "Enabling ON power level for usb device $usb_device."
		  elif [ -f /sys/bus/usb/devices/$usb_device/power/level ]; then
		      echo "on" > /sys/bus/usb/devices/$usb_device/power/level;
		      log "VERBOSE" "Enabling ON power level for usb device $usb_device."
		  else
		      log "VERBOSE" "Not enabling ON power level for usb device $usb_device"
		  fi
	      done
	  fi
    fi
else
    log "VERBOSE" "USB autosuspend is disabled."
fi

