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