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 modprobe test_firmware
      9 
     10 DIR=/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.
     15 HAS_FW_LOADER_USER_HELPER=$(if [ -d /sys/class/firmware/ ]; then echo yes; else echo no; fi)
     16 
     17 if [ "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then
     18 	OLD_TIMEOUT=$(cat /sys/class/firmware/timeout)
     19 fi
     20 
     21 OLD_FWPATH=$(cat /sys/module/firmware_class/parameters/path)
     22 
     23 FWPATH=$(mktemp -d)
     24 FW="$FWPATH/test-firmware.bin"
     25 
     26 test_finish()
     27 {
     28 	if [ "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then
     29 		echo "$OLD_TIMEOUT" >/sys/class/firmware/timeout
     30 	fi
     31 	echo -n "$OLD_PATH" >/sys/module/firmware_class/parameters/path
     32 	rm -f "$FW"
     33 	rmdir "$FWPATH"
     34 }
     35 
     36 trap "test_finish" EXIT
     37 
     38 if [ "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then
     39 	# Turn down the timeout so failures don't take so long.
     40 	echo 1 >/sys/class/firmware/timeout
     41 fi
     42 
     43 # Set the kernel search path.
     44 echo -n "$FWPATH" >/sys/module/firmware_class/parameters/path
     45 
     46 # This is an unlikely real-world firmware content. :)
     47 echo "ABCD0123" >"$FW"
     48 
     49 NAME=$(basename "$FW")
     50 
     51 if printf '\000' >"$DIR"/trigger_request; then
     52 	echo "$0: empty filename should not succeed" >&2
     53 	exit 1
     54 fi
     55 
     56 if printf '\000' >"$DIR"/trigger_async_request; then
     57 	echo "$0: empty filename should not succeed (async)" >&2
     58 	exit 1
     59 fi
     60 
     61 # Request a firmware that doesn't exist, it should fail.
     62 if echo -n "nope-$NAME" >"$DIR"/trigger_request; then
     63 	echo "$0: firmware shouldn't have loaded" >&2
     64 	exit 1
     65 fi
     66 if diff -q "$FW" /dev/test_firmware >/dev/null ; then
     67 	echo "$0: firmware was not expected to match" >&2
     68 	exit 1
     69 else
     70 	if [ "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then
     71 		echo "$0: timeout works"
     72 	fi
     73 fi
     74 
     75 # This should succeed via kernel load or will fail after 1 second after
     76 # being handed over to the user helper, which won't find the fw either.
     77 if ! echo -n "$NAME" >"$DIR"/trigger_request ; then
     78 	echo "$0: could not trigger request" >&2
     79 	exit 1
     80 fi
     81 
     82 # Verify the contents are what we expect.
     83 if ! diff -q "$FW" /dev/test_firmware >/dev/null ; then
     84 	echo "$0: firmware was not loaded" >&2
     85 	exit 1
     86 else
     87 	echo "$0: filesystem loading works"
     88 fi
     89 
     90 # Try the asynchronous version too
     91 if ! echo -n "$NAME" >"$DIR"/trigger_async_request ; then
     92 	echo "$0: could not trigger async request" >&2
     93 	exit 1
     94 fi
     95 
     96 # Verify the contents are what we expect.
     97 if ! diff -q "$FW" /dev/test_firmware >/dev/null ; then
     98 	echo "$0: firmware was not loaded (async)" >&2
     99 	exit 1
    100 else
    101 	echo "$0: async filesystem loading works"
    102 fi
    103 
    104 exit 0
    105