1 #!/bin/bash 2 # SPDX-License-Identifier: GPL-2.0 3 4 # Library of helpers for test scripts. 5 set -e 6 7 DIR=/sys/devices/virtual/misc/test_firmware 8 9 PROC_CONFIG="/proc/config.gz" 10 TEST_DIR=$(dirname $0) 11 12 # Kselftest framework requirement - SKIP code is 4. 13 ksft_skip=4 14 15 print_reqs_exit() 16 { 17 echo "You must have the following enabled in your kernel:" >&2 18 cat $TEST_DIR/config >&2 19 exit $ksft_skip 20 } 21 22 test_modprobe() 23 { 24 if [ ! -d $DIR ]; then 25 print_reqs_exit 26 fi 27 } 28 29 check_mods() 30 { 31 trap "test_modprobe" EXIT 32 if [ ! -d $DIR ]; then 33 modprobe test_firmware 34 fi 35 if [ ! -f $PROC_CONFIG ]; then 36 if modprobe configs 2>/dev/null; then 37 echo "Loaded configs module" 38 if [ ! -f $PROC_CONFIG ]; then 39 echo "You must have the following enabled in your kernel:" >&2 40 cat $TEST_DIR/config >&2 41 echo "Resorting to old heuristics" >&2 42 fi 43 else 44 echo "Failed to load configs module, using old heuristics" >&2 45 fi 46 fi 47 } 48 49 check_setup() 50 { 51 HAS_FW_LOADER_USER_HELPER="$(kconfig_has CONFIG_FW_LOADER_USER_HELPER=y)" 52 HAS_FW_LOADER_USER_HELPER_FALLBACK="$(kconfig_has CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y)" 53 PROC_FW_IGNORE_SYSFS_FALLBACK="0" 54 PROC_FW_FORCE_SYSFS_FALLBACK="0" 55 56 if [ -z $PROC_SYS_DIR ]; then 57 PROC_SYS_DIR="/proc/sys/kernel" 58 fi 59 60 FW_PROC="${PROC_SYS_DIR}/firmware_config" 61 FW_FORCE_SYSFS_FALLBACK="$FW_PROC/force_sysfs_fallback" 62 FW_IGNORE_SYSFS_FALLBACK="$FW_PROC/ignore_sysfs_fallback" 63 64 if [ -f $FW_FORCE_SYSFS_FALLBACK ]; then 65 PROC_FW_FORCE_SYSFS_FALLBACK="$(cat $FW_FORCE_SYSFS_FALLBACK)" 66 fi 67 68 if [ -f $FW_IGNORE_SYSFS_FALLBACK ]; then 69 PROC_FW_IGNORE_SYSFS_FALLBACK="$(cat $FW_IGNORE_SYSFS_FALLBACK)" 70 fi 71 72 if [ "$PROC_FW_FORCE_SYSFS_FALLBACK" = "1" ]; then 73 HAS_FW_LOADER_USER_HELPER="yes" 74 HAS_FW_LOADER_USER_HELPER_FALLBACK="yes" 75 fi 76 77 if [ "$PROC_FW_IGNORE_SYSFS_FALLBACK" = "1" ]; then 78 HAS_FW_LOADER_USER_HELPER_FALLBACK="no" 79 HAS_FW_LOADER_USER_HELPER="no" 80 fi 81 82 if [ "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then 83 OLD_TIMEOUT="$(cat /sys/class/firmware/timeout)" 84 fi 85 86 OLD_FWPATH="$(cat /sys/module/firmware_class/parameters/path)" 87 } 88 89 verify_reqs() 90 { 91 if [ "$TEST_REQS_FW_SYSFS_FALLBACK" = "yes" ]; then 92 if [ ! "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then 93 echo "usermode helper disabled so ignoring test" 94 exit $ksft_skip 95 fi 96 fi 97 } 98 99 setup_tmp_file() 100 { 101 FWPATH=$(mktemp -d) 102 FW="$FWPATH/test-firmware.bin" 103 echo "ABCD0123" >"$FW" 104 NAME=$(basename "$FW") 105 if [ "$TEST_REQS_FW_SET_CUSTOM_PATH" = "yes" ]; then 106 echo -n "$FWPATH" >/sys/module/firmware_class/parameters/path 107 fi 108 } 109 110 __setup_random_file() 111 { 112 RANDOM_FILE_PATH="$(mktemp -p $FWPATH)" 113 # mktemp says dry-run -n is unsafe, so... 114 if [[ "$1" = "fake" ]]; then 115 rm -rf $RANDOM_FILE_PATH 116 sync 117 else 118 echo "ABCD0123" >"$RANDOM_FILE_PATH" 119 fi 120 echo $RANDOM_FILE_PATH 121 } 122 123 setup_random_file() 124 { 125 echo $(__setup_random_file) 126 } 127 128 setup_random_file_fake() 129 { 130 echo $(__setup_random_file fake) 131 } 132 133 proc_set_force_sysfs_fallback() 134 { 135 if [ -f $FW_FORCE_SYSFS_FALLBACK ]; then 136 echo -n $1 > $FW_FORCE_SYSFS_FALLBACK 137 check_setup 138 fi 139 } 140 141 proc_set_ignore_sysfs_fallback() 142 { 143 if [ -f $FW_IGNORE_SYSFS_FALLBACK ]; then 144 echo -n $1 > $FW_IGNORE_SYSFS_FALLBACK 145 check_setup 146 fi 147 } 148 149 proc_restore_defaults() 150 { 151 proc_set_force_sysfs_fallback 0 152 proc_set_ignore_sysfs_fallback 0 153 } 154 155 test_finish() 156 { 157 if [ "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then 158 echo "$OLD_TIMEOUT" >/sys/class/firmware/timeout 159 fi 160 if [ "$TEST_REQS_FW_SET_CUSTOM_PATH" = "yes" ]; then 161 if [ "$OLD_FWPATH" = "" ]; then 162 # A zero-length write won't work; write a null byte 163 printf '\000' >/sys/module/firmware_class/parameters/path 164 else 165 echo -n "$OLD_FWPATH" >/sys/module/firmware_class/parameters/path 166 fi 167 fi 168 if [ -f $FW ]; then 169 rm -f "$FW" 170 fi 171 if [ -d $FWPATH ]; then 172 rm -rf "$FWPATH" 173 fi 174 proc_restore_defaults 175 } 176 177 kconfig_has() 178 { 179 if [ -f $PROC_CONFIG ]; then 180 if zgrep -q $1 $PROC_CONFIG 2>/dev/null; then 181 echo "yes" 182 else 183 echo "no" 184 fi 185 else 186 # We currently don't have easy heuristics to infer this 187 # so best we can do is just try to use the kernel assuming 188 # you had enabled it. This matches the old behaviour. 189 if [ "$1" = "CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y" ]; then 190 echo "yes" 191 elif [ "$1" = "CONFIG_FW_LOADER_USER_HELPER=y" ]; then 192 if [ -d /sys/class/firmware/ ]; then 193 echo yes 194 else 195 echo no 196 fi 197 fi 198 fi 199 } 200