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
12print_reqs_exit()
13{
14	echo "You must have the following enabled in your kernel:" >&2
15	cat $TEST_DIR/config >&2
16	exit 1
17}
18
19test_modprobe()
20{
21	if [ ! -d $DIR ]; then
22		print_reqs_exit
23	fi
24}
25
26check_mods()
27{
28	trap "test_modprobe" EXIT
29	if [ ! -d $DIR ]; then
30		modprobe test_firmware
31	fi
32	if [ ! -f $PROC_CONFIG ]; then
33		if modprobe configs 2>/dev/null; then
34			echo "Loaded configs module"
35			if [ ! -f $PROC_CONFIG ]; then
36				echo "You must have the following enabled in your kernel:" >&2
37				cat $TEST_DIR/config >&2
38				echo "Resorting to old heuristics" >&2
39			fi
40		else
41			echo "Failed to load configs module, using old heuristics" >&2
42		fi
43	fi
44}
45
46check_setup()
47{
48	HAS_FW_LOADER_USER_HELPER="$(kconfig_has CONFIG_FW_LOADER_USER_HELPER=y)"
49	HAS_FW_LOADER_USER_HELPER_FALLBACK="$(kconfig_has CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y)"
50	PROC_FW_IGNORE_SYSFS_FALLBACK="0"
51	PROC_FW_FORCE_SYSFS_FALLBACK="0"
52
53	if [ -z $PROC_SYS_DIR ]; then
54		PROC_SYS_DIR="/proc/sys/kernel"
55	fi
56
57	FW_PROC="${PROC_SYS_DIR}/firmware_config"
58	FW_FORCE_SYSFS_FALLBACK="$FW_PROC/force_sysfs_fallback"
59	FW_IGNORE_SYSFS_FALLBACK="$FW_PROC/ignore_sysfs_fallback"
60
61	if [ -f $FW_FORCE_SYSFS_FALLBACK ]; then
62		PROC_FW_FORCE_SYSFS_FALLBACK="$(cat $FW_FORCE_SYSFS_FALLBACK)"
63	fi
64
65	if [ -f $FW_IGNORE_SYSFS_FALLBACK ]; then
66		PROC_FW_IGNORE_SYSFS_FALLBACK="$(cat $FW_IGNORE_SYSFS_FALLBACK)"
67	fi
68
69	if [ "$PROC_FW_FORCE_SYSFS_FALLBACK" = "1" ]; then
70		HAS_FW_LOADER_USER_HELPER="yes"
71		HAS_FW_LOADER_USER_HELPER_FALLBACK="yes"
72	fi
73
74	if [ "$PROC_FW_IGNORE_SYSFS_FALLBACK" = "1" ]; then
75		HAS_FW_LOADER_USER_HELPER_FALLBACK="no"
76		HAS_FW_LOADER_USER_HELPER="no"
77	fi
78
79	if [ "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then
80	       OLD_TIMEOUT="$(cat /sys/class/firmware/timeout)"
81	fi
82
83	OLD_FWPATH="$(cat /sys/module/firmware_class/parameters/path)"
84}
85
86verify_reqs()
87{
88	if [ "$TEST_REQS_FW_SYSFS_FALLBACK" = "yes" ]; then
89		if [ ! "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then
90			echo "usermode helper disabled so ignoring test"
91			exit 0
92		fi
93	fi
94}
95
96setup_tmp_file()
97{
98	FWPATH=$(mktemp -d)
99	FW="$FWPATH/test-firmware.bin"
100	echo "ABCD0123" >"$FW"
101	NAME=$(basename "$FW")
102	if [ "$TEST_REQS_FW_SET_CUSTOM_PATH" = "yes" ]; then
103		echo -n "$FWPATH" >/sys/module/firmware_class/parameters/path
104	fi
105}
106
107proc_set_force_sysfs_fallback()
108{
109	if [ -f $FW_FORCE_SYSFS_FALLBACK ]; then
110		echo -n $1 > $FW_FORCE_SYSFS_FALLBACK
111		check_setup
112	fi
113}
114
115proc_set_ignore_sysfs_fallback()
116{
117	if [ -f $FW_IGNORE_SYSFS_FALLBACK ]; then
118		echo -n $1 > $FW_IGNORE_SYSFS_FALLBACK
119		check_setup
120	fi
121}
122
123proc_restore_defaults()
124{
125	proc_set_force_sysfs_fallback 0
126	proc_set_ignore_sysfs_fallback 0
127}
128
129test_finish()
130{
131	if [ "$HAS_FW_LOADER_USER_HELPER" = "yes" ]; then
132		echo "$OLD_TIMEOUT" >/sys/class/firmware/timeout
133	fi
134	if [ "$OLD_FWPATH" = "" ]; then
135		OLD_FWPATH=" "
136	fi
137	if [ "$TEST_REQS_FW_SET_CUSTOM_PATH" = "yes" ]; then
138		echo -n "$OLD_FWPATH" >/sys/module/firmware_class/parameters/path
139	fi
140	if [ -f $FW ]; then
141		rm -f "$FW"
142	fi
143	if [ -d $FWPATH ]; then
144		rm -rf "$FWPATH"
145	fi
146	proc_restore_defaults
147}
148
149kconfig_has()
150{
151	if [ -f $PROC_CONFIG ]; then
152		if zgrep -q $1 $PROC_CONFIG 2>/dev/null; then
153			echo "yes"
154		else
155			echo "no"
156		fi
157	else
158		# We currently don't have easy heuristics to infer this
159		# so best we can do is just try to use the kernel assuming
160		# you had enabled it. This matches the old behaviour.
161		if [ "$1" = "CONFIG_FW_LOADER_USER_HELPER_FALLBACK=y" ]; then
162			echo "yes"
163		elif [ "$1" = "CONFIG_FW_LOADER_USER_HELPER=y" ]; then
164			if [ -d /sys/class/firmware/ ]; then
165				echo yes
166			else
167				echo no
168			fi
169		fi
170	fi
171}
172