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