162306a36Sopenharmony_ci#!/bin/bash 262306a36Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0 362306a36Sopenharmony_ci# This validates the user-initiated fw upload mechanism of the firmware 462306a36Sopenharmony_ci# loader. It verifies that one or more firmware devices can be created 562306a36Sopenharmony_ci# for a device driver. It also verifies the data transfer, the 662306a36Sopenharmony_ci# cancellation support, and the error flows. 762306a36Sopenharmony_ciset -e 862306a36Sopenharmony_ci 962306a36Sopenharmony_ciTEST_REQS_FW_UPLOAD="yes" 1062306a36Sopenharmony_ciTEST_DIR=$(dirname $0) 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ciprogress_states="preparing transferring programming" 1362306a36Sopenharmony_cierrors="hw-error 1462306a36Sopenharmony_ci timeout 1562306a36Sopenharmony_ci device-busy 1662306a36Sopenharmony_ci invalid-file-size 1762306a36Sopenharmony_ci read-write-error 1862306a36Sopenharmony_ci flash-wearout" 1962306a36Sopenharmony_cierror_abort="user-abort" 2062306a36Sopenharmony_cifwname1=fw1 2162306a36Sopenharmony_cifwname2=fw2 2262306a36Sopenharmony_cifwname3=fw3 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_cisource $TEST_DIR/fw_lib.sh 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_cicheck_mods 2762306a36Sopenharmony_cicheck_setup 2862306a36Sopenharmony_civerify_reqs 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_citrap "upload_finish" EXIT 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ciupload_finish() { 3362306a36Sopenharmony_ci local fwdevs="$fwname1 $fwname2 $fwname3" 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci for name in $fwdevs; do 3662306a36Sopenharmony_ci if [ -e "$DIR/$name" ]; then 3762306a36Sopenharmony_ci echo -n "$name" > "$DIR"/upload_unregister 3862306a36Sopenharmony_ci fi 3962306a36Sopenharmony_ci done 4062306a36Sopenharmony_ci} 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ciupload_fw() { 4362306a36Sopenharmony_ci local name="$1" 4462306a36Sopenharmony_ci local file="$2" 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci echo 1 > "$DIR"/"$name"/loading 4762306a36Sopenharmony_ci cat "$file" > "$DIR"/"$name"/data 4862306a36Sopenharmony_ci echo 0 > "$DIR"/"$name"/loading 4962306a36Sopenharmony_ci} 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_civerify_fw() { 5262306a36Sopenharmony_ci local name="$1" 5362306a36Sopenharmony_ci local file="$2" 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci echo -n "$name" > "$DIR"/config_upload_name 5662306a36Sopenharmony_ci if ! cmp "$file" "$DIR"/upload_read > /dev/null 2>&1; then 5762306a36Sopenharmony_ci echo "$0: firmware compare for $name did not match" >&2 5862306a36Sopenharmony_ci exit 1 5962306a36Sopenharmony_ci fi 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci echo "$0: firmware upload for $name works" >&2 6262306a36Sopenharmony_ci return 0 6362306a36Sopenharmony_ci} 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ciinject_error() { 6662306a36Sopenharmony_ci local name="$1" 6762306a36Sopenharmony_ci local status="$2" 6862306a36Sopenharmony_ci local error="$3" 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci echo 1 > "$DIR"/"$name"/loading 7162306a36Sopenharmony_ci echo -n "inject":"$status":"$error" > "$DIR"/"$name"/data 7262306a36Sopenharmony_ci echo 0 > "$DIR"/"$name"/loading 7362306a36Sopenharmony_ci} 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ciawait_status() { 7662306a36Sopenharmony_ci local name="$1" 7762306a36Sopenharmony_ci local expected="$2" 7862306a36Sopenharmony_ci local status 7962306a36Sopenharmony_ci local i 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci let i=0 8262306a36Sopenharmony_ci while [ $i -lt 50 ]; do 8362306a36Sopenharmony_ci status=$(cat "$DIR"/"$name"/status) 8462306a36Sopenharmony_ci if [ "$status" = "$expected" ]; then 8562306a36Sopenharmony_ci return 0; 8662306a36Sopenharmony_ci fi 8762306a36Sopenharmony_ci sleep 1e-03 8862306a36Sopenharmony_ci let i=$i+1 8962306a36Sopenharmony_ci done 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci echo "$0: Invalid status: Expected $expected, Actual $status" >&2 9262306a36Sopenharmony_ci return 1; 9362306a36Sopenharmony_ci} 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ciawait_idle() { 9662306a36Sopenharmony_ci local name="$1" 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci await_status "$name" "idle" 9962306a36Sopenharmony_ci return $? 10062306a36Sopenharmony_ci} 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ciexpect_error() { 10362306a36Sopenharmony_ci local name="$1" 10462306a36Sopenharmony_ci local expected="$2" 10562306a36Sopenharmony_ci local error=$(cat "$DIR"/"$name"/error) 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci if [ "$error" != "$expected" ]; then 10862306a36Sopenharmony_ci echo "Invalid error: Expected $expected, Actual $error" >&2 10962306a36Sopenharmony_ci return 1 11062306a36Sopenharmony_ci fi 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci return 0 11362306a36Sopenharmony_ci} 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_cirandom_firmware() { 11662306a36Sopenharmony_ci local bs="$1" 11762306a36Sopenharmony_ci local count="$2" 11862306a36Sopenharmony_ci local file=$(mktemp -p /tmp uploadfwXXX.bin) 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci dd if=/dev/urandom of="$file" bs="$bs" count="$count" > /dev/null 2>&1 12162306a36Sopenharmony_ci echo "$file" 12262306a36Sopenharmony_ci} 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_citest_upload_cancel() { 12562306a36Sopenharmony_ci local name="$1" 12662306a36Sopenharmony_ci local status 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci for status in $progress_states; do 12962306a36Sopenharmony_ci inject_error $name $status $error_abort 13062306a36Sopenharmony_ci if ! await_status $name $status; then 13162306a36Sopenharmony_ci exit 1 13262306a36Sopenharmony_ci fi 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci echo 1 > "$DIR"/"$name"/cancel 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci if ! await_idle $name; then 13762306a36Sopenharmony_ci exit 1 13862306a36Sopenharmony_ci fi 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci if ! expect_error $name "$status":"$error_abort"; then 14162306a36Sopenharmony_ci exit 1 14262306a36Sopenharmony_ci fi 14362306a36Sopenharmony_ci done 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci echo "$0: firmware upload cancellation works" 14662306a36Sopenharmony_ci return 0 14762306a36Sopenharmony_ci} 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_citest_error_handling() { 15062306a36Sopenharmony_ci local name=$1 15162306a36Sopenharmony_ci local status 15262306a36Sopenharmony_ci local error 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci for status in $progress_states; do 15562306a36Sopenharmony_ci for error in $errors; do 15662306a36Sopenharmony_ci inject_error $name $status $error 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci if ! await_idle $name; then 15962306a36Sopenharmony_ci exit 1 16062306a36Sopenharmony_ci fi 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci if ! expect_error $name "$status":"$error"; then 16362306a36Sopenharmony_ci exit 1 16462306a36Sopenharmony_ci fi 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ci done 16762306a36Sopenharmony_ci done 16862306a36Sopenharmony_ci echo "$0: firmware upload error handling works" 16962306a36Sopenharmony_ci} 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_citest_fw_too_big() { 17262306a36Sopenharmony_ci local name=$1 17362306a36Sopenharmony_ci local fw_too_big=`random_firmware 512 5` 17462306a36Sopenharmony_ci local expected="preparing:invalid-file-size" 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci upload_fw $name $fw_too_big 17762306a36Sopenharmony_ci rm -f $fw_too_big 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci if ! await_idle $name; then 18062306a36Sopenharmony_ci exit 1 18162306a36Sopenharmony_ci fi 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci if ! expect_error $name $expected; then 18462306a36Sopenharmony_ci exit 1 18562306a36Sopenharmony_ci fi 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci echo "$0: oversized firmware error handling works" 18862306a36Sopenharmony_ci} 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ciecho -n "$fwname1" > "$DIR"/upload_register 19162306a36Sopenharmony_ciecho -n "$fwname2" > "$DIR"/upload_register 19262306a36Sopenharmony_ciecho -n "$fwname3" > "$DIR"/upload_register 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_citest_upload_cancel $fwname1 19562306a36Sopenharmony_citest_error_handling $fwname1 19662306a36Sopenharmony_citest_fw_too_big $fwname1 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_cifw_file1=`random_firmware 512 4` 19962306a36Sopenharmony_cifw_file2=`random_firmware 512 3` 20062306a36Sopenharmony_cifw_file3=`random_firmware 512 2` 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_ciupload_fw $fwname1 $fw_file1 20362306a36Sopenharmony_ciupload_fw $fwname2 $fw_file2 20462306a36Sopenharmony_ciupload_fw $fwname3 $fw_file3 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_civerify_fw ${fwname1} ${fw_file1} 20762306a36Sopenharmony_civerify_fw ${fwname2} ${fw_file2} 20862306a36Sopenharmony_civerify_fw ${fwname3} ${fw_file3} 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_ciecho -n "$fwname1" > "$DIR"/upload_unregister 21162306a36Sopenharmony_ciecho -n "$fwname2" > "$DIR"/upload_unregister 21262306a36Sopenharmony_ciecho -n "$fwname3" > "$DIR"/upload_unregister 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ciexit 0 215