Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/tools/testing/selftests/firmware/fw_upload.sh
26285 views
1
#!/bin/bash
2
# SPDX-License-Identifier: GPL-2.0
3
# This validates the user-initiated fw upload mechanism of the firmware
4
# loader. It verifies that one or more firmware devices can be created
5
# for a device driver. It also verifies the data transfer, the
6
# cancellation support, and the error flows.
7
set -e
8
9
TEST_REQS_FW_UPLOAD="yes"
10
TEST_DIR=$(dirname $0)
11
12
progress_states="preparing transferring programming"
13
errors="hw-error
14
timeout
15
device-busy
16
invalid-file-size
17
read-write-error
18
flash-wearout"
19
error_abort="user-abort"
20
fwname1=fw1
21
fwname2=fw2
22
fwname3=fw3
23
24
source $TEST_DIR/fw_lib.sh
25
26
check_mods
27
check_setup
28
verify_reqs
29
30
trap "upload_finish" EXIT
31
32
upload_finish() {
33
local fwdevs="$fwname1 $fwname2 $fwname3"
34
35
for name in $fwdevs; do
36
if [ -e "$DIR/$name" ]; then
37
echo -n "$name" > "$DIR"/upload_unregister
38
fi
39
done
40
}
41
42
upload_fw() {
43
local name="$1"
44
local file="$2"
45
46
echo 1 > "$DIR"/"$name"/loading
47
cat "$file" > "$DIR"/"$name"/data
48
echo 0 > "$DIR"/"$name"/loading
49
}
50
51
verify_fw() {
52
local name="$1"
53
local file="$2"
54
55
echo -n "$name" > "$DIR"/config_upload_name
56
if ! cmp "$file" "$DIR"/upload_read > /dev/null 2>&1; then
57
echo "$0: firmware compare for $name did not match" >&2
58
exit 1
59
fi
60
61
echo "$0: firmware upload for $name works" >&2
62
return 0
63
}
64
65
inject_error() {
66
local name="$1"
67
local status="$2"
68
local error="$3"
69
70
echo 1 > "$DIR"/"$name"/loading
71
echo -n "inject":"$status":"$error" > "$DIR"/"$name"/data
72
echo 0 > "$DIR"/"$name"/loading
73
}
74
75
await_status() {
76
local name="$1"
77
local expected="$2"
78
local status
79
local i
80
81
let i=0
82
while [ $i -lt 50 ]; do
83
status=$(cat "$DIR"/"$name"/status)
84
if [ "$status" = "$expected" ]; then
85
return 0;
86
fi
87
sleep 1e-03
88
let i=$i+1
89
done
90
91
echo "$0: Invalid status: Expected $expected, Actual $status" >&2
92
return 1;
93
}
94
95
await_idle() {
96
local name="$1"
97
98
await_status "$name" "idle"
99
return $?
100
}
101
102
expect_error() {
103
local name="$1"
104
local expected="$2"
105
local error=$(cat "$DIR"/"$name"/error)
106
107
if [ "$error" != "$expected" ]; then
108
echo "Invalid error: Expected $expected, Actual $error" >&2
109
return 1
110
fi
111
112
return 0
113
}
114
115
random_firmware() {
116
local bs="$1"
117
local count="$2"
118
local file=$(mktemp -p /tmp uploadfwXXX.bin)
119
120
dd if=/dev/urandom of="$file" bs="$bs" count="$count" > /dev/null 2>&1
121
echo "$file"
122
}
123
124
test_upload_cancel() {
125
local name="$1"
126
local status
127
128
for status in $progress_states; do
129
inject_error $name $status $error_abort
130
if ! await_status $name $status; then
131
exit 1
132
fi
133
134
echo 1 > "$DIR"/"$name"/cancel
135
136
if ! await_idle $name; then
137
exit 1
138
fi
139
140
if ! expect_error $name "$status":"$error_abort"; then
141
exit 1
142
fi
143
done
144
145
echo "$0: firmware upload cancellation works"
146
return 0
147
}
148
149
test_error_handling() {
150
local name=$1
151
local status
152
local error
153
154
for status in $progress_states; do
155
for error in $errors; do
156
inject_error $name $status $error
157
158
if ! await_idle $name; then
159
exit 1
160
fi
161
162
if ! expect_error $name "$status":"$error"; then
163
exit 1
164
fi
165
166
done
167
done
168
echo "$0: firmware upload error handling works"
169
}
170
171
test_fw_too_big() {
172
local name=$1
173
local fw_too_big=`random_firmware 512 5`
174
local expected="preparing:invalid-file-size"
175
176
upload_fw $name $fw_too_big
177
rm -f $fw_too_big
178
179
if ! await_idle $name; then
180
exit 1
181
fi
182
183
if ! expect_error $name $expected; then
184
exit 1
185
fi
186
187
echo "$0: oversized firmware error handling works"
188
}
189
190
echo -n "$fwname1" > "$DIR"/upload_register
191
echo -n "$fwname2" > "$DIR"/upload_register
192
echo -n "$fwname3" > "$DIR"/upload_register
193
194
test_upload_cancel $fwname1
195
test_error_handling $fwname1
196
test_fw_too_big $fwname1
197
198
fw_file1=`random_firmware 512 4`
199
fw_file2=`random_firmware 512 3`
200
fw_file3=`random_firmware 512 2`
201
202
upload_fw $fwname1 $fw_file1
203
upload_fw $fwname2 $fw_file2
204
upload_fw $fwname3 $fw_file3
205
206
verify_fw ${fwname1} ${fw_file1}
207
verify_fw ${fwname2} ${fw_file2}
208
verify_fw ${fwname3} ${fw_file3}
209
210
echo -n "$fwname1" > "$DIR"/upload_unregister
211
echo -n "$fwname2" > "$DIR"/upload_unregister
212
echo -n "$fwname3" > "$DIR"/upload_unregister
213
214
exit 0
215
216