1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3 4# Library of helpers for test scripts. 5set -e 6 7DIR=/sys/devices/virtual/misc/test_firmware 8 9PROC_CONFIG="/proc/config.gz" 10TEST_DIR=$(dirname $0) 11 12# Kselftest framework requirement - SKIP code is 4. 13ksft_skip=4 14 15print_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 22test_modprobe() 23{ 24 if [ ! -d $DIR ]; then 25 print_reqs_exit 26 fi 27} 28 29check_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 49check_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 89verify_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 99setup_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 123setup_random_file() 124{ 125 echo $(__setup_random_file) 126} 127 128setup_random_file_fake() 129{ 130 echo $(__setup_random_file fake) 131} 132 133proc_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 141proc_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 149proc_restore_defaults() 150{ 151 proc_set_force_sysfs_fallback 0 152 proc_set_ignore_sysfs_fallback 0 153} 154 155test_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 177kconfig_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