2 # SPDX-License-Identifier: GPL-2.0
3 # This validates that the kernel will fall back to using the fallback mechanism
4 # to load firmware it can't find on disk itself. We must request a firmware
5 # that the kernel won't find, and any installed helper (e.g. udev) also
6 # won't find so that we can do the load ourself manually.
9 TEST_REQS_FW_SYSFS_FALLBACK
="yes"
10 TEST_REQS_FW_SET_CUSTOM_PATH
="no"
11 TEST_DIR
=$
(dirname $0)
12 source $TEST_DIR/fw_lib.sh
19 trap "test_finish" EXIT
26 # This will block until our load (below) has finished.
27 echo -n "$name" >"$DIR"/trigger_request
&
29 # Give kernel a chance to react.
31 while [ ! -e "$DIR"/"$name"/loading
]; do
33 timeout
=$
(( $timeout - 1 ))
34 if [ "$timeout" -eq 0 ]; then
35 echo "$0: firmware interface never appeared" >&2
40 echo 1 >"$DIR"/"$name"/loading
41 cat "$file" >"$DIR"/"$name"/data
42 echo 0 >"$DIR"/"$name"/loading
44 # Wait for request to finish.
53 # This will block until our load (below) has finished.
54 echo -n "$name" >"$DIR"/trigger_request
2>/dev
/null
&
56 # Give kernel a chance to react.
58 while [ ! -e "$DIR"/"$name"/loading
]; do
60 timeout
=$
(( $timeout - 1 ))
61 if [ "$timeout" -eq 0 ]; then
62 echo "$0: firmware interface never appeared" >&2
67 echo -1 >"$DIR"/"$name"/loading
69 # Wait for request to finish.
75 if [ ! -e "$DIR"/trigger_custom_fallback
]; then
76 echo "$0: custom fallback trigger not present, ignoring test" >&2
83 echo -n "$name" >"$DIR"/trigger_custom_fallback
2>/dev
/null
&
85 # Give kernel a chance to react.
87 while [ ! -e "$DIR"/"$name"/loading
]; do
89 timeout
=$
(( $timeout - 1 ))
90 if [ "$timeout" -eq 0 ]; then
91 echo "$0: firmware interface never appeared" >&2
96 echo 1 >"$DIR"/"$name"/loading
97 cat "$file" >"$DIR"/"$name"/data
98 echo 0 >"$DIR"/"$name"/loading
100 # Wait for request to finish.
106 load_fw_custom_cancel
()
108 if [ ! -e "$DIR"/trigger_custom_fallback
]; then
109 echo "$0: canceling custom fallback trigger not present, ignoring test" >&2
116 echo -n "$name" >"$DIR"/trigger_custom_fallback
2>/dev
/null
&
118 # Give kernel a chance to react.
120 while [ ! -e "$DIR"/"$name"/loading
]; do
122 timeout
=$
(( $timeout - 1 ))
123 if [ "$timeout" -eq 0 ]; then
124 echo "$0: firmware interface never appeared" >&2
129 echo -1 >"$DIR"/"$name"/loading
131 # Wait for request to finish.
136 load_fw_fallback_with_child
()
141 # This is the value already set but we want to be explicit
142 echo 4 >/sys
/class
/firmware
/timeout
145 SECONDS_BEFORE
=$
(date +%s
)
146 echo -n "$name" >"$DIR"/trigger_request
2>/dev
/null
147 SECONDS_AFTER
=$
(date +%s
)
148 SECONDS_DELTA
=$
(($SECONDS_AFTER - $SECONDS_BEFORE))
149 if [ "$SECONDS_DELTA" -lt 4 ]; then
160 DEVPATH
="$DIR"/"nope-$NAME"/loading
162 # Test failure when doing nothing (timeout works).
163 echo -n 2 >/sys
/class
/firmware
/timeout
164 echo -n "nope-$NAME" >"$DIR"/trigger_request
2>/dev
/null
&
166 # Give the kernel some time to load the loading file, must be less
167 # than the timeout above.
169 if [ ! -f $DEVPATH ]; then
170 echo "$0: fallback mechanism immediately cancelled"
172 echo "The file never appeared: $DEVPATH"
174 echo "This might be a distribution udev rule setup by your distribution"
175 echo "to immediately cancel all fallback requests, this must be"
176 echo "removed before running these tests. To confirm look for"
177 echo "a firmware rule like /lib/udev/rules.d/50-firmware.rules"
178 echo "and see if you have something like this:"
180 echo "SUBSYSTEM==\"firmware\", ACTION==\"add\", ATTR{loading}=\"-1\""
182 echo "If you do remove this file or comment out this line before"
183 echo "proceeding with these tests."
187 if diff -q "$FW" /dev
/test_firmware
>/dev
/null
; then
188 echo "$0: firmware was not expected to match" >&2
191 echo "$0: timeout works"
195 run_sysfs_main_tests
()
198 # Put timeout high enough for us to do work but not so long that failures
199 # slow down this test too much.
200 echo 4 >/sys
/class
/firmware
/timeout
202 # Load this script instead of the desired firmware.
204 if diff -q "$FW" /dev
/test_firmware
>/dev
/null
; then
205 echo "$0: firmware was not expected to match" >&2
208 echo "$0: firmware comparison works"
211 # Do a proper load, which should work correctly.
212 load_fw
"$NAME" "$FW"
213 if ! diff -q "$FW" /dev
/test_firmware
>/dev
/null
; then
214 echo "$0: firmware was not loaded" >&2
217 echo "$0: fallback mechanism works"
220 load_fw_cancel
"nope-$NAME" "$FW"
221 if diff -q "$FW" /dev
/test_firmware
>/dev
/null
; then
222 echo "$0: firmware was expected to be cancelled" >&2
225 echo "$0: cancelling fallback mechanism works"
229 load_fw_fallback_with_child
"nope-signal-$NAME" "$FW"
230 if [ "$?" -eq 0 ]; then
231 echo "$0: SIGCHLD on sync ignored as expected" >&2
233 echo "$0: error - sync firmware request cancelled due to SIGCHLD" >&2
239 run_sysfs_custom_load_tests
()
241 RANDOM_FILE_PATH
=$
(setup_random_file
)
242 RANDOM_FILE
="$(basename $RANDOM_FILE_PATH)"
243 if load_fw_custom
"$RANDOM_FILE" "$RANDOM_FILE_PATH" ; then
244 if ! diff -q "$RANDOM_FILE_PATH" /dev
/test_firmware
>/dev
/null
; then
245 echo "$0: firmware was not loaded" >&2
248 echo "$0: custom fallback loading mechanism works"
252 RANDOM_FILE_PATH
=$
(setup_random_file
)
253 RANDOM_FILE
="$(basename $RANDOM_FILE_PATH)"
254 if load_fw_custom
"$RANDOM_FILE" "$RANDOM_FILE_PATH" ; then
255 if ! diff -q "$RANDOM_FILE_PATH" /dev
/test_firmware
>/dev
/null
; then
256 echo "$0: firmware was not loaded" >&2
259 echo "$0: custom fallback loading mechanism works"
263 RANDOM_FILE_REAL
="$RANDOM_FILE_PATH"
264 FAKE_RANDOM_FILE_PATH
=$
(setup_random_file_fake
)
265 FAKE_RANDOM_FILE
="$(basename $FAKE_RANDOM_FILE_PATH)"
267 if load_fw_custom_cancel
"$FAKE_RANDOM_FILE" "$RANDOM_FILE_REAL" ; then
268 if diff -q "$RANDOM_FILE_PATH" /dev
/test_firmware
>/dev
/null
; then
269 echo "$0: firmware was expected to be cancelled" >&2
272 echo "$0: cancelling custom fallback mechanism works"
277 if [ "$HAS_FW_LOADER_USER_HELPER_FALLBACK" = "yes" ]; then
281 run_sysfs_custom_load_tests