• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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