1#!/bin/sh 2# This validates that the kernel will fall back to using the user helper 3# to load firmware it can't find on disk itself. We must request a firmware 4# that the kernel won't find, and any installed helper (e.g. udev) also 5# won't find so that we can do the load ourself manually. 6set -e 7 8modprobe test_firmware 9 10DIR=/sys/devices/virtual/misc/test_firmware 11 12# CONFIG_FW_LOADER_USER_HELPER has a sysfs class under /sys/class/firmware/ 13# These days no one enables CONFIG_FW_LOADER_USER_HELPER so check for that 14# as an indicator for CONFIG_FW_LOADER_USER_HELPER. 15HAS_FW_LOADER_USER_HELPER=$(if [ -d /sys/class/firmware/ ]; then echo yes; else echo no; fi) 16 17if [ "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then 18 OLD_TIMEOUT=$(cat /sys/class/firmware/timeout) 19else 20 echo "usermode helper disabled so ignoring test" 21 exit 0 22fi 23 24FWPATH=$(mktemp -d) 25FW="$FWPATH/test-firmware.bin" 26 27test_finish() 28{ 29 echo "$OLD_TIMEOUT" >/sys/class/firmware/timeout 30 rm -f "$FW" 31 rmdir "$FWPATH" 32} 33 34load_fw() 35{ 36 local name="$1" 37 local file="$2" 38 39 # This will block until our load (below) has finished. 40 echo -n "$name" >"$DIR"/trigger_request & 41 42 # Give kernel a chance to react. 43 local timeout=10 44 while [ ! -e "$DIR"/"$name"/loading ]; do 45 sleep 0.1 46 timeout=$(( $timeout - 1 )) 47 if [ "$timeout" -eq 0 ]; then 48 echo "$0: firmware interface never appeared" >&2 49 exit 1 50 fi 51 done 52 53 echo 1 >"$DIR"/"$name"/loading 54 cat "$file" >"$DIR"/"$name"/data 55 echo 0 >"$DIR"/"$name"/loading 56 57 # Wait for request to finish. 58 wait 59} 60 61trap "test_finish" EXIT 62 63# This is an unlikely real-world firmware content. :) 64echo "ABCD0123" >"$FW" 65NAME=$(basename "$FW") 66 67# Test failure when doing nothing (timeout works). 68echo 1 >/sys/class/firmware/timeout 69echo -n "$NAME" >"$DIR"/trigger_request 70if diff -q "$FW" /dev/test_firmware >/dev/null ; then 71 echo "$0: firmware was not expected to match" >&2 72 exit 1 73else 74 echo "$0: timeout works" 75fi 76 77# Put timeout high enough for us to do work but not so long that failures 78# slow down this test too much. 79echo 4 >/sys/class/firmware/timeout 80 81# Load this script instead of the desired firmware. 82load_fw "$NAME" "$0" 83if diff -q "$FW" /dev/test_firmware >/dev/null ; then 84 echo "$0: firmware was not expected to match" >&2 85 exit 1 86else 87 echo "$0: firmware comparison works" 88fi 89 90# Do a proper load, which should work correctly. 91load_fw "$NAME" "$FW" 92if ! diff -q "$FW" /dev/test_firmware >/dev/null ; then 93 echo "$0: firmware was not loaded" >&2 94 exit 1 95else 96 echo "$0: user helper firmware loading works" 97fi 98 99exit 0 100