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