215 lines
3.9 KiB
Bash
Executable File
215 lines
3.9 KiB
Bash
Executable File
#!/bin/bash
|
|
# SPDX-License-Identifier: GPL-2.0
|
|
# This validates the user-initiated fw upload mechanism of the firmware
|
|
# loader. It verifies that one or more firmware devices can be created
|
|
# for a device driver. It also verifies the data transfer, the
|
|
# cancellation support, and the error flows.
|
|
set -e
|
|
|
|
TEST_REQS_FW_UPLOAD="yes"
|
|
TEST_DIR=$(dirname $0)
|
|
|
|
progress_states="preparing transferring programming"
|
|
errors="hw-error
|
|
timeout
|
|
device-busy
|
|
invalid-file-size
|
|
read-write-error
|
|
flash-wearout"
|
|
error_abort="user-abort"
|
|
fwname1=fw1
|
|
fwname2=fw2
|
|
fwname3=fw3
|
|
|
|
source $TEST_DIR/fw_lib.sh
|
|
|
|
check_mods
|
|
check_setup
|
|
verify_reqs
|
|
|
|
trap "upload_finish" EXIT
|
|
|
|
upload_finish() {
|
|
local fwdevs="$fwname1 $fwname2 $fwname3"
|
|
|
|
for name in $fwdevs; do
|
|
if [ -e "$DIR/$name" ]; then
|
|
echo -n "$name" > "$DIR"/upload_unregister
|
|
fi
|
|
done
|
|
}
|
|
|
|
upload_fw() {
|
|
local name="$1"
|
|
local file="$2"
|
|
|
|
echo 1 > "$DIR"/"$name"/loading
|
|
cat "$file" > "$DIR"/"$name"/data
|
|
echo 0 > "$DIR"/"$name"/loading
|
|
}
|
|
|
|
verify_fw() {
|
|
local name="$1"
|
|
local file="$2"
|
|
|
|
echo -n "$name" > "$DIR"/config_upload_name
|
|
if ! cmp "$file" "$DIR"/upload_read > /dev/null 2>&1; then
|
|
echo "$0: firmware compare for $name did not match" >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "$0: firmware upload for $name works" >&2
|
|
return 0
|
|
}
|
|
|
|
inject_error() {
|
|
local name="$1"
|
|
local status="$2"
|
|
local error="$3"
|
|
|
|
echo 1 > "$DIR"/"$name"/loading
|
|
echo -n "inject":"$status":"$error" > "$DIR"/"$name"/data
|
|
echo 0 > "$DIR"/"$name"/loading
|
|
}
|
|
|
|
await_status() {
|
|
local name="$1"
|
|
local expected="$2"
|
|
local status
|
|
local i
|
|
|
|
let i=0
|
|
while [ $i -lt 50 ]; do
|
|
status=$(cat "$DIR"/"$name"/status)
|
|
if [ "$status" = "$expected" ]; then
|
|
return 0;
|
|
fi
|
|
sleep 1e-03
|
|
let i=$i+1
|
|
done
|
|
|
|
echo "$0: Invalid status: Expected $expected, Actual $status" >&2
|
|
return 1;
|
|
}
|
|
|
|
await_idle() {
|
|
local name="$1"
|
|
|
|
await_status "$name" "idle"
|
|
return $?
|
|
}
|
|
|
|
expect_error() {
|
|
local name="$1"
|
|
local expected="$2"
|
|
local error=$(cat "$DIR"/"$name"/error)
|
|
|
|
if [ "$error" != "$expected" ]; then
|
|
echo "Invalid error: Expected $expected, Actual $error" >&2
|
|
return 1
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
random_firmware() {
|
|
local bs="$1"
|
|
local count="$2"
|
|
local file=$(mktemp -p /tmp uploadfwXXX.bin)
|
|
|
|
dd if=/dev/urandom of="$file" bs="$bs" count="$count" > /dev/null 2>&1
|
|
echo "$file"
|
|
}
|
|
|
|
test_upload_cancel() {
|
|
local name="$1"
|
|
local status
|
|
|
|
for status in $progress_states; do
|
|
inject_error $name $status $error_abort
|
|
if ! await_status $name $status; then
|
|
exit 1
|
|
fi
|
|
|
|
echo 1 > "$DIR"/"$name"/cancel
|
|
|
|
if ! await_idle $name; then
|
|
exit 1
|
|
fi
|
|
|
|
if ! expect_error $name "$status":"$error_abort"; then
|
|
exit 1
|
|
fi
|
|
done
|
|
|
|
echo "$0: firmware upload cancellation works"
|
|
return 0
|
|
}
|
|
|
|
test_error_handling() {
|
|
local name=$1
|
|
local status
|
|
local error
|
|
|
|
for status in $progress_states; do
|
|
for error in $errors; do
|
|
inject_error $name $status $error
|
|
|
|
if ! await_idle $name; then
|
|
exit 1
|
|
fi
|
|
|
|
if ! expect_error $name "$status":"$error"; then
|
|
exit 1
|
|
fi
|
|
|
|
done
|
|
done
|
|
echo "$0: firmware upload error handling works"
|
|
}
|
|
|
|
test_fw_too_big() {
|
|
local name=$1
|
|
local fw_too_big=`random_firmware 512 5`
|
|
local expected="preparing:invalid-file-size"
|
|
|
|
upload_fw $name $fw_too_big
|
|
rm -f $fw_too_big
|
|
|
|
if ! await_idle $name; then
|
|
exit 1
|
|
fi
|
|
|
|
if ! expect_error $name $expected; then
|
|
exit 1
|
|
fi
|
|
|
|
echo "$0: oversized firmware error handling works"
|
|
}
|
|
|
|
echo -n "$fwname1" > "$DIR"/upload_register
|
|
echo -n "$fwname2" > "$DIR"/upload_register
|
|
echo -n "$fwname3" > "$DIR"/upload_register
|
|
|
|
test_upload_cancel $fwname1
|
|
test_error_handling $fwname1
|
|
test_fw_too_big $fwname1
|
|
|
|
fw_file1=`random_firmware 512 4`
|
|
fw_file2=`random_firmware 512 3`
|
|
fw_file3=`random_firmware 512 2`
|
|
|
|
upload_fw $fwname1 $fw_file1
|
|
upload_fw $fwname2 $fw_file2
|
|
upload_fw $fwname3 $fw_file3
|
|
|
|
verify_fw ${fwname1} ${fw_file1}
|
|
verify_fw ${fwname2} ${fw_file2}
|
|
verify_fw ${fwname3} ${fw_file3}
|
|
|
|
echo -n "$fwname1" > "$DIR"/upload_unregister
|
|
echo -n "$fwname2" > "$DIR"/upload_unregister
|
|
echo -n "$fwname3" > "$DIR"/upload_unregister
|
|
|
|
exit 0
|