Loading...
Note: File does not exist in v3.1.
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3# This validates that the kernel will load firmware out of its list of
4# firmware locations on disk. Since the user helper does similar work,
5# we reset the custom load directory to a location the user helper doesn't
6# know so we can be sure we're not accidentally testing the user helper.
7set -e
8
9TEST_REQS_FW_SYSFS_FALLBACK="no"
10TEST_REQS_FW_SET_CUSTOM_PATH="yes"
11TEST_DIR=$(dirname $0)
12source $TEST_DIR/fw_lib.sh
13
14check_mods
15check_setup
16verify_reqs
17setup_tmp_file
18
19trap "test_finish" EXIT
20
21if [ "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then
22 # Turn down the timeout so failures don't take so long.
23 echo 1 >/sys/class/firmware/timeout
24fi
25
26if printf '\000' >"$DIR"/trigger_request 2> /dev/null; then
27 echo "$0: empty filename should not succeed" >&2
28 exit 1
29fi
30
31if [ ! -e "$DIR"/trigger_async_request ]; then
32 echo "$0: empty filename: async trigger not present, ignoring test" >&2
33 exit $ksft_skip
34else
35 if printf '\000' >"$DIR"/trigger_async_request 2> /dev/null; then
36 echo "$0: empty filename should not succeed (async)" >&2
37 exit 1
38 fi
39fi
40
41# Request a firmware that doesn't exist, it should fail.
42if echo -n "nope-$NAME" >"$DIR"/trigger_request 2> /dev/null; then
43 echo "$0: firmware shouldn't have loaded" >&2
44 exit 1
45fi
46if diff -q "$FW" /dev/test_firmware >/dev/null ; then
47 echo "$0: firmware was not expected to match" >&2
48 exit 1
49else
50 if [ "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then
51 echo "$0: timeout works"
52 fi
53fi
54
55# This should succeed via kernel load or will fail after 1 second after
56# being handed over to the user helper, which won't find the fw either.
57if ! echo -n "$NAME" >"$DIR"/trigger_request ; then
58 echo "$0: could not trigger request" >&2
59 exit 1
60fi
61
62# Verify the contents are what we expect.
63if ! diff -q "$FW" /dev/test_firmware >/dev/null ; then
64 echo "$0: firmware was not loaded" >&2
65 exit 1
66else
67 echo "$0: filesystem loading works"
68fi
69
70# Try the asynchronous version too
71if [ ! -e "$DIR"/trigger_async_request ]; then
72 echo "$0: firmware loading: async trigger not present, ignoring test" >&2
73 exit $ksft_skip
74else
75 if ! echo -n "$NAME" >"$DIR"/trigger_async_request ; then
76 echo "$0: could not trigger async request" >&2
77 exit 1
78 fi
79
80 # Verify the contents are what we expect.
81 if ! diff -q "$FW" /dev/test_firmware >/dev/null ; then
82 echo "$0: firmware was not loaded (async)" >&2
83 exit 1
84 else
85 echo "$0: async filesystem loading works"
86 fi
87fi
88
89### Batched requests tests
90test_config_present()
91{
92 if [ ! -f $DIR/reset ]; then
93 echo "Configuration triggers not present, ignoring test"
94 exit $ksft_skip
95 fi
96}
97
98# Defaults :
99#
100# send_uevent: 1
101# sync_direct: 0
102# name: test-firmware.bin
103# num_requests: 4
104config_reset()
105{
106 echo 1 > $DIR/reset
107}
108
109release_all_firmware()
110{
111 echo 1 > $DIR/release_all_firmware
112}
113
114config_set_name()
115{
116 echo -n $1 > $DIR/config_name
117}
118
119config_set_into_buf()
120{
121 echo 1 > $DIR/config_into_buf
122}
123
124config_unset_into_buf()
125{
126 echo 0 > $DIR/config_into_buf
127}
128
129config_set_sync_direct()
130{
131 echo 1 > $DIR/config_sync_direct
132}
133
134config_unset_sync_direct()
135{
136 echo 0 > $DIR/config_sync_direct
137}
138
139config_set_uevent()
140{
141 echo 1 > $DIR/config_send_uevent
142}
143
144config_unset_uevent()
145{
146 echo 0 > $DIR/config_send_uevent
147}
148
149config_trigger_sync()
150{
151 echo -n 1 > $DIR/trigger_batched_requests 2>/dev/null
152}
153
154config_trigger_async()
155{
156 echo -n 1 > $DIR/trigger_batched_requests_async 2> /dev/null
157}
158
159config_set_read_fw_idx()
160{
161 echo -n $1 > $DIR/config_read_fw_idx 2> /dev/null
162}
163
164read_firmwares()
165{
166 if [ "$(cat $DIR/config_into_buf)" == "1" ]; then
167 fwfile="$FW_INTO_BUF"
168 else
169 fwfile="$FW"
170 fi
171 if [ "$1" = "xzonly" ]; then
172 fwfile="${fwfile}-orig"
173 fi
174 for i in $(seq 0 3); do
175 config_set_read_fw_idx $i
176 # Verify the contents are what we expect.
177 # -Z required for now -- check for yourself, md5sum
178 # on $FW and DIR/read_firmware will yield the same. Even
179 # cmp agrees, so something is off.
180 if ! diff -q -Z "$fwfile" $DIR/read_firmware 2>/dev/null ; then
181 echo "request #$i: firmware was not loaded" >&2
182 exit 1
183 fi
184 done
185}
186
187read_firmwares_expect_nofile()
188{
189 for i in $(seq 0 3); do
190 config_set_read_fw_idx $i
191 # Ensures contents differ
192 if diff -q -Z "$FW" $DIR/read_firmware 2>/dev/null ; then
193 echo "request $i: file was not expected to match" >&2
194 exit 1
195 fi
196 done
197}
198
199test_batched_request_firmware_nofile()
200{
201 echo -n "Batched request_firmware() nofile try #$1: "
202 config_reset
203 config_set_name nope-test-firmware.bin
204 config_trigger_sync
205 read_firmwares_expect_nofile
206 release_all_firmware
207 echo "OK"
208}
209
210test_batched_request_firmware_into_buf_nofile()
211{
212 echo -n "Batched request_firmware_into_buf() nofile try #$1: "
213 config_reset
214 config_set_name nope-test-firmware.bin
215 config_set_into_buf
216 config_trigger_sync
217 read_firmwares_expect_nofile
218 release_all_firmware
219 echo "OK"
220}
221
222test_batched_request_firmware_direct_nofile()
223{
224 echo -n "Batched request_firmware_direct() nofile try #$1: "
225 config_reset
226 config_set_name nope-test-firmware.bin
227 config_set_sync_direct
228 config_trigger_sync
229 release_all_firmware
230 echo "OK"
231}
232
233test_request_firmware_nowait_uevent_nofile()
234{
235 echo -n "Batched request_firmware_nowait(uevent=true) nofile try #$1: "
236 config_reset
237 config_set_name nope-test-firmware.bin
238 config_trigger_async
239 release_all_firmware
240 echo "OK"
241}
242
243test_wait_and_cancel_custom_load()
244{
245 if [ "$HAS_FW_LOADER_USER_HELPER" != "yes" ]; then
246 return
247 fi
248 local timeout=10
249 name=$1
250 while [ ! -e "$DIR"/"$name"/loading ]; do
251 sleep 0.1
252 timeout=$(( $timeout - 1 ))
253 if [ "$timeout" -eq 0 ]; then
254 echo "firmware interface never appeared:" >&2
255 echo "$DIR/$name/loading" >&2
256 exit 1
257 fi
258 done
259 echo -1 >"$DIR"/"$name"/loading
260}
261
262test_request_firmware_nowait_custom_nofile()
263{
264 echo -n "Batched request_firmware_nowait(uevent=false) nofile try #$1: "
265 config_reset
266 config_unset_uevent
267 RANDOM_FILE_PATH=$(setup_random_file_fake)
268 RANDOM_FILE="$(basename $RANDOM_FILE_PATH)"
269 config_set_name $RANDOM_FILE
270 config_trigger_async &
271 test_wait_and_cancel_custom_load $RANDOM_FILE
272 wait
273 release_all_firmware
274 echo "OK"
275}
276
277test_batched_request_firmware()
278{
279 echo -n "Batched request_firmware() $2 try #$1: "
280 config_reset
281 config_trigger_sync
282 read_firmwares $2
283 release_all_firmware
284 echo "OK"
285}
286
287test_batched_request_firmware_into_buf()
288{
289 echo -n "Batched request_firmware_into_buf() $2 try #$1: "
290 config_reset
291 config_set_name $TEST_FIRMWARE_INTO_BUF_FILENAME
292 config_set_into_buf
293 config_trigger_sync
294 read_firmwares $2
295 release_all_firmware
296 echo "OK"
297}
298
299test_batched_request_firmware_direct()
300{
301 echo -n "Batched request_firmware_direct() $2 try #$1: "
302 config_reset
303 config_set_sync_direct
304 config_trigger_sync
305 release_all_firmware
306 echo "OK"
307}
308
309test_request_firmware_nowait_uevent()
310{
311 echo -n "Batched request_firmware_nowait(uevent=true) $2 try #$1: "
312 config_reset
313 config_trigger_async
314 release_all_firmware
315 echo "OK"
316}
317
318test_request_firmware_nowait_custom()
319{
320 echo -n "Batched request_firmware_nowait(uevent=false) $2 try #$1: "
321 config_reset
322 config_unset_uevent
323 RANDOM_FILE_PATH=$(setup_random_file)
324 RANDOM_FILE="$(basename $RANDOM_FILE_PATH)"
325 if [ "$2" = "both" ]; then
326 xz -9 -C crc32 -k $RANDOM_FILE_PATH
327 elif [ "$2" = "xzonly" ]; then
328 xz -9 -C crc32 $RANDOM_FILE_PATH
329 fi
330 config_set_name $RANDOM_FILE
331 config_trigger_async
332 release_all_firmware
333 echo "OK"
334}
335
336# Only continue if batched request triggers are present on the
337# test-firmware driver
338test_config_present
339
340# test with the file present
341echo
342echo "Testing with the file present..."
343for i in $(seq 1 5); do
344 test_batched_request_firmware $i normal
345done
346
347for i in $(seq 1 5); do
348 test_batched_request_firmware_into_buf $i normal
349done
350
351for i in $(seq 1 5); do
352 test_batched_request_firmware_direct $i normal
353done
354
355for i in $(seq 1 5); do
356 test_request_firmware_nowait_uevent $i normal
357done
358
359for i in $(seq 1 5); do
360 test_request_firmware_nowait_custom $i normal
361done
362
363# Test for file not found, errors are expected, the failure would be
364# a hung task, which would require a hard reset.
365echo
366echo "Testing with the file missing..."
367for i in $(seq 1 5); do
368 test_batched_request_firmware_nofile $i
369done
370
371for i in $(seq 1 5); do
372 test_batched_request_firmware_into_buf_nofile $i
373done
374
375for i in $(seq 1 5); do
376 test_batched_request_firmware_direct_nofile $i
377done
378
379for i in $(seq 1 5); do
380 test_request_firmware_nowait_uevent_nofile $i
381done
382
383for i in $(seq 1 5); do
384 test_request_firmware_nowait_custom_nofile $i
385done
386
387test "$HAS_FW_LOADER_COMPRESS" != "yes" && exit 0
388
389# test with both files present
390xz -9 -C crc32 -k $FW
391config_set_name $NAME
392echo
393echo "Testing with both plain and xz files present..."
394for i in $(seq 1 5); do
395 test_batched_request_firmware $i both
396done
397
398for i in $(seq 1 5); do
399 test_batched_request_firmware_into_buf $i both
400done
401
402for i in $(seq 1 5); do
403 test_batched_request_firmware_direct $i both
404done
405
406for i in $(seq 1 5); do
407 test_request_firmware_nowait_uevent $i both
408done
409
410for i in $(seq 1 5); do
411 test_request_firmware_nowait_custom $i both
412done
413
414# test with only xz file present
415mv "$FW" "${FW}-orig"
416echo
417echo "Testing with only xz file present..."
418for i in $(seq 1 5); do
419 test_batched_request_firmware $i xzonly
420done
421
422for i in $(seq 1 5); do
423 test_batched_request_firmware_into_buf $i xzonly
424done
425
426for i in $(seq 1 5); do
427 test_batched_request_firmware_direct $i xzonly
428done
429
430for i in $(seq 1 5); do
431 test_request_firmware_nowait_uevent $i xzonly
432done
433
434for i in $(seq 1 5); do
435 test_request_firmware_nowait_custom $i xzonly
436done
437
438exit 0