Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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_sync_direct()
120{
121 echo 1 > $DIR/config_sync_direct
122}
123
124config_unset_sync_direct()
125{
126 echo 0 > $DIR/config_sync_direct
127}
128
129config_set_uevent()
130{
131 echo 1 > $DIR/config_send_uevent
132}
133
134config_unset_uevent()
135{
136 echo 0 > $DIR/config_send_uevent
137}
138
139config_trigger_sync()
140{
141 echo -n 1 > $DIR/trigger_batched_requests 2>/dev/null
142}
143
144config_trigger_async()
145{
146 echo -n 1 > $DIR/trigger_batched_requests_async 2> /dev/null
147}
148
149config_set_read_fw_idx()
150{
151 echo -n $1 > $DIR/config_read_fw_idx 2> /dev/null
152}
153
154read_firmwares()
155{
156 for i in $(seq 0 3); do
157 config_set_read_fw_idx $i
158 # Verify the contents are what we expect.
159 # -Z required for now -- check for yourself, md5sum
160 # on $FW and DIR/read_firmware will yield the same. Even
161 # cmp agrees, so something is off.
162 if ! diff -q -Z "$FW" $DIR/read_firmware 2>/dev/null ; then
163 echo "request #$i: firmware was not loaded" >&2
164 exit 1
165 fi
166 done
167}
168
169read_firmwares_expect_nofile()
170{
171 for i in $(seq 0 3); do
172 config_set_read_fw_idx $i
173 # Ensures contents differ
174 if diff -q -Z "$FW" $DIR/read_firmware 2>/dev/null ; then
175 echo "request $i: file was not expected to match" >&2
176 exit 1
177 fi
178 done
179}
180
181test_batched_request_firmware_nofile()
182{
183 echo -n "Batched request_firmware() nofile try #$1: "
184 config_reset
185 config_set_name nope-test-firmware.bin
186 config_trigger_sync
187 read_firmwares_expect_nofile
188 release_all_firmware
189 echo "OK"
190}
191
192test_batched_request_firmware_direct_nofile()
193{
194 echo -n "Batched request_firmware_direct() nofile try #$1: "
195 config_reset
196 config_set_name nope-test-firmware.bin
197 config_set_sync_direct
198 config_trigger_sync
199 release_all_firmware
200 echo "OK"
201}
202
203test_request_firmware_nowait_uevent_nofile()
204{
205 echo -n "Batched request_firmware_nowait(uevent=true) nofile try #$1: "
206 config_reset
207 config_set_name nope-test-firmware.bin
208 config_trigger_async
209 release_all_firmware
210 echo "OK"
211}
212
213test_wait_and_cancel_custom_load()
214{
215 if [ "$HAS_FW_LOADER_USER_HELPER" != "yes" ]; then
216 return
217 fi
218 local timeout=10
219 name=$1
220 while [ ! -e "$DIR"/"$name"/loading ]; do
221 sleep 0.1
222 timeout=$(( $timeout - 1 ))
223 if [ "$timeout" -eq 0 ]; then
224 echo "firmware interface never appeared:" >&2
225 echo "$DIR/$name/loading" >&2
226 exit 1
227 fi
228 done
229 echo -1 >"$DIR"/"$name"/loading
230}
231
232test_request_firmware_nowait_custom_nofile()
233{
234 echo -n "Batched request_firmware_nowait(uevent=false) nofile try #$1: "
235 config_reset
236 config_unset_uevent
237 RANDOM_FILE_PATH=$(setup_random_file_fake)
238 RANDOM_FILE="$(basename $RANDOM_FILE_PATH)"
239 config_set_name $RANDOM_FILE
240 config_trigger_async &
241 test_wait_and_cancel_custom_load $RANDOM_FILE
242 wait
243 release_all_firmware
244 echo "OK"
245}
246
247test_batched_request_firmware()
248{
249 echo -n "Batched request_firmware() try #$1: "
250 config_reset
251 config_trigger_sync
252 read_firmwares
253 release_all_firmware
254 echo "OK"
255}
256
257test_batched_request_firmware_direct()
258{
259 echo -n "Batched request_firmware_direct() try #$1: "
260 config_reset
261 config_set_sync_direct
262 config_trigger_sync
263 release_all_firmware
264 echo "OK"
265}
266
267test_request_firmware_nowait_uevent()
268{
269 echo -n "Batched request_firmware_nowait(uevent=true) try #$1: "
270 config_reset
271 config_trigger_async
272 release_all_firmware
273 echo "OK"
274}
275
276test_request_firmware_nowait_custom()
277{
278 echo -n "Batched request_firmware_nowait(uevent=false) try #$1: "
279 config_reset
280 config_unset_uevent
281 RANDOM_FILE_PATH=$(setup_random_file)
282 RANDOM_FILE="$(basename $RANDOM_FILE_PATH)"
283 config_set_name $RANDOM_FILE
284 config_trigger_async
285 release_all_firmware
286 echo "OK"
287}
288
289# Only continue if batched request triggers are present on the
290# test-firmware driver
291test_config_present
292
293# test with the file present
294echo
295echo "Testing with the file present..."
296for i in $(seq 1 5); do
297 test_batched_request_firmware $i
298done
299
300for i in $(seq 1 5); do
301 test_batched_request_firmware_direct $i
302done
303
304for i in $(seq 1 5); do
305 test_request_firmware_nowait_uevent $i
306done
307
308for i in $(seq 1 5); do
309 test_request_firmware_nowait_custom $i
310done
311
312# Test for file not found, errors are expected, the failure would be
313# a hung task, which would require a hard reset.
314echo
315echo "Testing with the file missing..."
316for i in $(seq 1 5); do
317 test_batched_request_firmware_nofile $i
318done
319
320for i in $(seq 1 5); do
321 test_batched_request_firmware_direct_nofile $i
322done
323
324for i in $(seq 1 5); do
325 test_request_firmware_nowait_uevent_nofile $i
326done
327
328for i in $(seq 1 5); do
329 test_request_firmware_nowait_custom_nofile $i
330done
331
332exit 0