#!/bin/sh
# Firmware loader.
# See also:
# https://www.kernel.org/doc/Documentation/firmware_class/README
# https://www.kernel.org/doc/Documentation/firmware_class/hotplug-script
set -e

# handle only firmware add requests
if [ "$SUBSYSTEM" != "firmware" ]; then
	exit 0
fi
if [ "$ACTION" != "add" ]; then
	exit 0
fi

FIRMWARE_DIRS="/lib/firmware/updates/$(uname -r) /lib/firmware/updates \
               /lib/firmware/$(uname -r) /lib/firmware"

# @param string message
# @param int loglevel. defaults to "6" (info)
# Log levels can be:
# Name      String  Meaning
# KERN_EMERG    "0" Emergency messages, system is about to crash or is unstable
# KERN_ALERT    "1" Something bad happened and action must be taken immediately
# KERN_CRIT "2" A critical condition occurred like a serious hardware/software failure
# KERN_ERR  "3" An error condition, often used by drivers to indicate difficulties with the hardware
# KERN_WARNING  "4" A warning, meaning nothing serious by itself but might indicate problems
# KERN_NOTICE   "5" Nothing serious, but notably nevertheless. Often used to report security events.
# KERN_INFO "6" Informational message e.g. startup information at driver initialization
# KERN_DEBUG    "7" Debug messages
# KERN_CONT "c" "continued" line of log printout (only done after a line that had no enclosing \n)
kmsg() {
    local msg="$1" level=${2:-3}
    echo "<$level>$msg" > /dev/kmsg
}

err() {
	echo >&2 "$*"
	kmsg "${0##*/}[$$] $*"
}

if [ ! -e /sys$DEVPATH/loading ]; then
	err "firmware loader misses sysfs directory"
	exit 1
fi

for DIR in $FIRMWARE_DIRS; do
	[ -e "$DIR/$FIRMWARE" ] || continue
	echo 1 > /sys$DEVPATH/loading
	cat "$DIR/$FIRMWARE" > /sys$DEVPATH/data
	echo 0 > /sys$DEVPATH/loading
	exit 0
done

echo -1 > /sys$DEVPATH/loading
err "Cannot find firmware file '$FIRMWARE'"
exit 1
