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# We need to load a different file to test request_firmware_into_buf 13# I believe the issue is firmware loaded cached vs. non-cached 14# with same filename is bungled. 15# To reproduce rename this to test-firmware.bin 16TEST_FIRMWARE_INTO_BUF_FILENAME=test-firmware-into-buf.bin 17 18# Kselftest framework requirement - SKIP code is 4. 19ksft_skip=4 20 21print_reqs_exit() 22{ 23 echo "You must have the following enabled in your kernel:" >&2 24 cat $TEST_DIR/config >&2 25 exit $ksft_skip 26} 27 28test_modprobe() 29{ 30 if [ ! -d $DIR ]; then 31 print_reqs_exit 32 fi 33} 34 35check_mods() 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 HAS_FW_LOADER_COMPRESS="$(kconfig_has CONFIG_FW_LOADER_COMPRESS=y)" 60 PROC_FW_IGNORE_SYSFS_FALLBACK="0" 61 PROC_FW_FORCE_SYSFS_FALLBACK="0" 62 63 if [ -z $PROC_SYS_DIR ]; then 64 PROC_SYS_DIR="/proc/sys/kernel" 65 fi 66 67 FW_PROC="${PROC_SYS_DIR}/firmware_config" 68 FW_FORCE_SYSFS_FALLBACK="$FW_PROC/force_sysfs_fallback" 69 FW_IGNORE_SYSFS_FALLBACK="$FW_PROC/ignore_sysfs_fallback" 70 71 if [ -f $FW_FORCE_SYSFS_FALLBACK ]; then 72 PROC_FW_FORCE_SYSFS_FALLBACK="$(cat $FW_FORCE_SYSFS_FALLBACK)" 73 fi 74 75 if [ -f $FW_IGNORE_SYSFS_FALLBACK ]; then 76 PROC_FW_IGNORE_SYSFS_FALLBACK="$(cat $FW_IGNORE_SYSFS_FALLBACK)" 77 fi 78 79 if [ "$PROC_FW_FORCE_SYSFS_FALLBACK" = "1" ]; then 80 HAS_FW_LOADER_USER_HELPER="yes" 81 HAS_FW_LOADER_USER_HELPER_FALLBACK="yes" 82 fi 83 84 if [ "$PROC_FW_IGNORE_SYSFS_FALLBACK" = "1" ]; then 85 HAS_FW_LOADER_USER_HELPER_FALLBACK="no" 86 HAS_FW_LOADER_USER_HELPER="no" 87 fi 88 89 if [ "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then 90 OLD_TIMEOUT="$(cat /sys/class/firmware/timeout)" 91 fi 92 93 OLD_FWPATH="$(cat /sys/module/firmware_class/parameters/path)" 94 95 if [ "$HAS_FW_LOADER_COMPRESS" = "yes" ]; then 96 if ! which xz 2> /dev/null > /dev/null; then 97 HAS_FW_LOADER_COMPRESS="" 98 fi 99 fi 100} 101 102verify_reqs() 103{ 104 if [ "$TEST_REQS_FW_SYSFS_FALLBACK" = "yes" ]; then 105 if [ ! "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then 106 echo "usermode helper disabled so ignoring test" 107 exit 0 108 fi 109 fi 110} 111 112setup_tmp_file() 113{ 114 FWPATH=$(mktemp -d) 115 FW="$FWPATH/test-firmware.bin" 116 echo "ABCD0123" >"$FW" 117 FW_INTO_BUF="$FWPATH/$TEST_FIRMWARE_INTO_BUF_FILENAME" 118 echo "EFGH4567" >"$FW_INTO_BUF" 119 NAME=$(basename "$FW") 120 if [ "$TEST_REQS_FW_SET_CUSTOM_PATH" = "yes" ]; then 121 echo -n "$FWPATH" >/sys/module/firmware_class/parameters/path 122 fi 123} 124 125__setup_random_file() 126{ 127 RANDOM_FILE_PATH="$(mktemp -p $FWPATH)" 128 # mktemp says dry-run -n is unsafe, so... 129 if [[ "$1" = "fake" ]]; then 130 rm -rf $RANDOM_FILE_PATH 131 sync 132 else 133 echo "ABCD0123" >"$RANDOM_FILE_PATH" 134 fi 135 echo $RANDOM_FILE_PATH 136} 137 138setup_random_file() 139{ 140 echo $(__setup_random_file) 141} 142 143setup_random_file_fake() 144{ 145 echo $(__setup_random_file fake) 146} 147 148proc_set_force_sysfs_fallback() 149{ 150 if [ -f $FW_FORCE_SYSFS_FALLBACK ]; then 151 echo -n $1 > $FW_FORCE_SYSFS_FALLBACK 152 check_setup 153 fi 154} 155 156proc_set_ignore_sysfs_fallback() 157{ 158 if [ -f $FW_IGNORE_SYSFS_FALLBACK ]; then 159 echo -n $1 > $FW_IGNORE_SYSFS_FALLBACK 160 check_setup 161 fi 162} 163 164proc_restore_defaults() 165{ 166 proc_set_force_sysfs_fallback 0 167 proc_set_ignore_sysfs_fallback 0 168} 169 170test_finish() 171{ 172 if [ "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then 173 echo "$OLD_TIMEOUT" >/sys/class/firmware/timeout 174 fi 175 if [ "$TEST_REQS_FW_SET_CUSTOM_PATH" = "yes" ]; then 176 if [ "$OLD_FWPATH" = "" ]; then 177 # A zero-length write won't work; write a null byte 178 printf '\000' >/sys/module/firmware_class/parameters/path 179 else 180 echo -n "$OLD_FWPATH" >/sys/module/firmware_class/parameters/path 181 fi 182 fi 183 if [ -f $FW ]; then 184 rm -f "$FW" 185 fi 186 if [ -f $FW_INTO_BUF ]; then 187 rm -f "$FW_INTO_BUF" 188 fi 189 if [ -d $FWPATH ]; then 190 rm -rf "$FWPATH" 191 fi 192 proc_restore_defaults 193} 194 195kconfig_has() 196{ 197 if [ -f $PROC_CONFIG ]; then 198 if zgrep -q $1 $PROC_CONFIG 2>/dev/null; then 199 echo "yes" 200 else 201 echo "no" 202 fi 203 else 204 # We currently don't have easy heuristics to infer this 205 # so best we can do is just try to use the kernel assuming 206 # you had enabled it. This matches the old behaviour. 207 if [ "$1" = "CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y" ]; then 208 echo "yes" 209 elif [ "$1" = "CONFIG_FW_LOADER_USER_HELPER=y" ]; then 210 if [ -d /sys/class/firmware/ ]; then 211 echo yes 212 else 213 echo no 214 fi 215 fi 216 fi 217} 218