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