diff options
Diffstat (limited to 'tools/testing/selftests/firmware/fw_userhelper.sh')
-rw-r--r-- | tools/testing/selftests/firmware/fw_userhelper.sh | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/tools/testing/selftests/firmware/fw_userhelper.sh b/tools/testing/selftests/firmware/fw_userhelper.sh new file mode 100644 index 000000000000..6efbade12139 --- /dev/null +++ b/tools/testing/selftests/firmware/fw_userhelper.sh | |||
@@ -0,0 +1,89 @@ | |||
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. | ||
6 | set -e | ||
7 | |||
8 | modprobe test_firmware | ||
9 | |||
10 | DIR=/sys/devices/virtual/misc/test_firmware | ||
11 | |||
12 | OLD_TIMEOUT=$(cat /sys/class/firmware/timeout) | ||
13 | |||
14 | FWPATH=$(mktemp -d) | ||
15 | FW="$FWPATH/test-firmware.bin" | ||
16 | |||
17 | test_finish() | ||
18 | { | ||
19 | echo "$OLD_TIMEOUT" >/sys/class/firmware/timeout | ||
20 | rm -f "$FW" | ||
21 | rmdir "$FWPATH" | ||
22 | } | ||
23 | |||
24 | load_fw() | ||
25 | { | ||
26 | local name="$1" | ||
27 | local file="$2" | ||
28 | |||
29 | # This will block until our load (below) has finished. | ||
30 | echo -n "$name" >"$DIR"/trigger_request & | ||
31 | |||
32 | # Give kernel a chance to react. | ||
33 | local timeout=10 | ||
34 | while [ ! -e "$DIR"/"$name"/loading ]; do | ||
35 | sleep 0.1 | ||
36 | timeout=$(( $timeout - 1 )) | ||
37 | if [ "$timeout" -eq 0 ]; then | ||
38 | echo "$0: firmware interface never appeared" >&2 | ||
39 | exit 1 | ||
40 | fi | ||
41 | done | ||
42 | |||
43 | echo 1 >"$DIR"/"$name"/loading | ||
44 | cat "$file" >"$DIR"/"$name"/data | ||
45 | echo 0 >"$DIR"/"$name"/loading | ||
46 | |||
47 | # Wait for request to finish. | ||
48 | wait | ||
49 | } | ||
50 | |||
51 | trap "test_finish" EXIT | ||
52 | |||
53 | # This is an unlikely real-world firmware content. :) | ||
54 | echo "ABCD0123" >"$FW" | ||
55 | NAME=$(basename "$FW") | ||
56 | |||
57 | # Test failure when doing nothing (timeout works). | ||
58 | echo 1 >/sys/class/firmware/timeout | ||
59 | echo -n "$NAME" >"$DIR"/trigger_request | ||
60 | if diff -q "$FW" /dev/test_firmware >/dev/null ; then | ||
61 | echo "$0: firmware was not expected to match" >&2 | ||
62 | exit 1 | ||
63 | else | ||
64 | echo "$0: timeout works" | ||
65 | fi | ||
66 | |||
67 | # Put timeout high enough for us to do work but not so long that failures | ||
68 | # slow down this test too much. | ||
69 | echo 4 >/sys/class/firmware/timeout | ||
70 | |||
71 | # Load this script instead of the desired firmware. | ||
72 | load_fw "$NAME" "$0" | ||
73 | if diff -q "$FW" /dev/test_firmware >/dev/null ; then | ||
74 | echo "$0: firmware was not expected to match" >&2 | ||
75 | exit 1 | ||
76 | else | ||
77 | echo "$0: firmware comparison works" | ||
78 | fi | ||
79 | |||
80 | # Do a proper load, which should work correctly. | ||
81 | load_fw "$NAME" "$FW" | ||
82 | if ! diff -q "$FW" /dev/test_firmware >/dev/null ; then | ||
83 | echo "$0: firmware was not loaded" >&2 | ||
84 | exit 1 | ||
85 | else | ||
86 | echo "$0: user helper firmware loading works" | ||
87 | fi | ||
88 | |||
89 | exit 0 | ||