Home | History | Annotate | Download | only in firmware
      1 #!/bin/sh
      2 # This validates that the kernel will load firmware out of its list of
      3 # firmware locations on disk. Since the user helper does similar work,
      4 # we reset the custom load directory to a location the user helper doesn't
      5 # know so we can be sure we're not accidentally testing the user helper.
      6 set -e
      7 
      8 DIR=/sys/devices/virtual/misc/test_firmware
      9 TEST_DIR=$(dirname $0)
     10 
     11 test_modprobe()
     12 {
     13 	if [ ! -d $DIR ]; then
     14 		echo "$0: $DIR not present"
     15 		echo "You must have the following enabled in your kernel:"
     16 		cat $TEST_DIR/config
     17 		exit 1
     18 	fi
     19 }
     20 
     21 trap "test_modprobe" EXIT
     22 
     23 if [ ! -d $DIR ]; then
     24 	modprobe test_firmware
     25 fi
     26 
     27 # CONFIG_FW_LOADER_USER_HELPER has a sysfs class under /sys/class/firmware/
     28 # These days no one enables CONFIG_FW_LOADER_USER_HELPER so check for that
     29 # as an indicator for CONFIG_FW_LOADER_USER_HELPER.
     30 HAS_FW_LOADER_USER_HELPER=$(if [ -d /sys/class/firmware/ ]; then echo yes; else echo no; fi)
     31 
     32 if [ "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then
     33 	OLD_TIMEOUT=$(cat /sys/class/firmware/timeout)
     34 fi
     35 
     36 OLD_FWPATH=$(cat /sys/module/firmware_class/parameters/path)
     37 
     38 FWPATH=$(mktemp -d)
     39 FW="$FWPATH/test-firmware.bin"
     40 
     41 test_finish()
     42 {
     43 	if [ "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then
     44 		echo "$OLD_TIMEOUT" >/sys/class/firmware/timeout
     45 	fi
     46 	echo -n "$OLD_PATH" >/sys/module/firmware_class/parameters/path
     47 	rm -f "$FW"
     48 	rmdir "$FWPATH"
     49 }
     50 
     51 trap "test_finish" EXIT
     52 
     53 if [ "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then
     54 	# Turn down the timeout so failures don't take so long.
     55 	echo 1 >/sys/class/firmware/timeout
     56 fi
     57 
     58 # Set the kernel search path.
     59 echo -n "$FWPATH" >/sys/module/firmware_class/parameters/path
     60 
     61 # This is an unlikely real-world firmware content. :)
     62 echo "ABCD0123" >"$FW"
     63 
     64 NAME=$(basename "$FW")
     65 
     66 if printf '\000' >"$DIR"/trigger_request 2> /dev/null; then
     67 	echo "$0: empty filename should not succeed" >&2
     68 	exit 1
     69 fi
     70 
     71 if printf '\000' >"$DIR"/trigger_async_request 2> /dev/null; then
     72 	echo "$0: empty filename should not succeed (async)" >&2
     73 	exit 1
     74 fi
     75 
     76 # Request a firmware that doesn't exist, it should fail.
     77 if echo -n "nope-$NAME" >"$DIR"/trigger_request 2> /dev/null; then
     78 	echo "$0: firmware shouldn't have loaded" >&2
     79 	exit 1
     80 fi
     81 if diff -q "$FW" /dev/test_firmware >/dev/null ; then
     82 	echo "$0: firmware was not expected to match" >&2
     83 	exit 1
     84 else
     85 	if [ "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then
     86 		echo "$0: timeout works"
     87 	fi
     88 fi
     89 
     90 # This should succeed via kernel load or will fail after 1 second after
     91 # being handed over to the user helper, which won't find the fw either.
     92 if ! echo -n "$NAME" >"$DIR"/trigger_request ; then
     93 	echo "$0: could not trigger request" >&2
     94 	exit 1
     95 fi
     96 
     97 # Verify the contents are what we expect.
     98 if ! diff -q "$FW" /dev/test_firmware >/dev/null ; then
     99 	echo "$0: firmware was not loaded" >&2
    100 	exit 1
    101 else
    102 	echo "$0: filesystem loading works"
    103 fi
    104 
    105 # Try the asynchronous version too
    106 if ! echo -n "$NAME" >"$DIR"/trigger_async_request ; then
    107 	echo "$0: could not trigger async request" >&2
    108 	exit 1
    109 fi
    110 
    111 # Verify the contents are what we expect.
    112 if ! diff -q "$FW" /dev/test_firmware >/dev/null ; then
    113 	echo "$0: firmware was not loaded (async)" >&2
    114 	exit 1
    115 else
    116 	echo "$0: async filesystem loading works"
    117 fi
    118 
    119 exit 0
    120