123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- #!/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
|