brintos

brintos / linux-shallow public Read only

0
0
Text · 6.6 KiB · 70d18be Raw
284 lines · bash
1#!/bin/bash2# SPDX-License-Identifier: GPL-2.03# This validates that the kernel will fall back to using the fallback mechanism4# to load firmware it can't find on disk itself. We must request a firmware5# that the kernel won't find, and any installed helper (e.g. udev) also6# won't find so that we can do the load ourself manually.7set -e8 9TEST_REQS_FW_SYSFS_FALLBACK="yes"10TEST_REQS_FW_SET_CUSTOM_PATH="no"11TEST_DIR=$(dirname $0)12source $TEST_DIR/fw_lib.sh13 14check_mods15check_setup16verify_reqs17setup_tmp_file18 19trap "test_finish" EXIT20 21load_fw()22{23	local name="$1"24	local file="$2"25 26	# This will block until our load (below) has finished.27	echo -n "$name" >"$DIR"/trigger_request &28 29	# Give kernel a chance to react.30	local timeout=1031	while [ ! -e "$DIR"/"$name"/loading ]; do32		sleep 0.133		timeout=$(( $timeout - 1 ))34		if [ "$timeout" -eq 0 ]; then35			echo "$0: firmware interface never appeared" >&236			exit 137		fi38	done39 40	echo 1 >"$DIR"/"$name"/loading41	cat "$file" >"$DIR"/"$name"/data42	echo 0 >"$DIR"/"$name"/loading43 44	# Wait for request to finish.45	wait46}47 48load_fw_cancel()49{50	local name="$1"51	local file="$2"52 53	# This will block until our load (below) has finished.54	echo -n "$name" >"$DIR"/trigger_request 2>/dev/null &55 56	# Give kernel a chance to react.57	local timeout=1058	while [ ! -e "$DIR"/"$name"/loading ]; do59		sleep 0.160		timeout=$(( $timeout - 1 ))61		if [ "$timeout" -eq 0 ]; then62			echo "$0: firmware interface never appeared" >&263			exit 164		fi65	done66 67	echo -1 >"$DIR"/"$name"/loading68 69	# Wait for request to finish.70	wait71}72 73load_fw_custom()74{75	if [ ! -e "$DIR"/trigger_custom_fallback ]; then76		echo "$0: custom fallback trigger not present, ignoring test" >&277		exit $ksft_skip78	fi79 80	local name="$1"81	local file="$2"82 83	echo -n "$name" >"$DIR"/trigger_custom_fallback 2>/dev/null &84 85	# Give kernel a chance to react.86	local timeout=1087	while [ ! -e "$DIR"/"$name"/loading ]; do88		sleep 0.189		timeout=$(( $timeout - 1 ))90		if [ "$timeout" -eq 0 ]; then91			echo "$0: firmware interface never appeared" >&292			exit 193		fi94	done95 96	echo 1 >"$DIR"/"$name"/loading97	cat "$file" >"$DIR"/"$name"/data98	echo 0 >"$DIR"/"$name"/loading99 100	# Wait for request to finish.101	wait102	return 0103}104 105 106load_fw_custom_cancel()107{108	if [ ! -e "$DIR"/trigger_custom_fallback ]; then109		echo "$0: canceling custom fallback trigger not present, ignoring test" >&2110		exit $ksft_skip111	fi112 113	local name="$1"114	local file="$2"115 116	echo -n "$name" >"$DIR"/trigger_custom_fallback 2>/dev/null &117 118	# Give kernel a chance to react.119	local timeout=10120	while [ ! -e "$DIR"/"$name"/loading ]; do121		sleep 0.1122		timeout=$(( $timeout - 1 ))123		if [ "$timeout" -eq 0 ]; then124			echo "$0: firmware interface never appeared" >&2125			exit 1126		fi127	done128 129	echo -1 >"$DIR"/"$name"/loading130 131	# Wait for request to finish.132	wait133	return 0134}135 136load_fw_fallback_with_child()137{138	local name="$1"139	local file="$2"140 141	# This is the value already set but we want to be explicit142	echo 4 >/sys/class/firmware/timeout143 144	sleep 1 &145	SECONDS_BEFORE=$(date +%s)146	echo -n "$name" >"$DIR"/trigger_request 2>/dev/null147	SECONDS_AFTER=$(date +%s)148	SECONDS_DELTA=$(($SECONDS_AFTER - $SECONDS_BEFORE))149	if [ "$SECONDS_DELTA" -lt 4 ]; then150		RET=1151	else152		RET=0153	fi154	wait155	return $RET156}157 158test_syfs_timeout()159{160	DEVPATH="$DIR"/"nope-$NAME"/loading161 162	# Test failure when doing nothing (timeout works).163	echo -n 2 >/sys/class/firmware/timeout164	echo -n "nope-$NAME" >"$DIR"/trigger_request 2>/dev/null &165 166	# Give the kernel some time to load the loading file, must be less167	# than the timeout above.168	sleep 1169	if [ ! -f $DEVPATH ]; then170		echo "$0: fallback mechanism immediately cancelled"171		echo ""172		echo "The file never appeared: $DEVPATH"173		echo ""174		echo "This might be a distribution udev rule setup by your distribution"175		echo "to immediately cancel all fallback requests, this must be"176		echo "removed before running these tests. To confirm look for"177		echo "a firmware rule like /lib/udev/rules.d/50-firmware.rules"178		echo "and see if you have something like this:"179		echo ""180		echo "SUBSYSTEM==\"firmware\", ACTION==\"add\", ATTR{loading}=\"-1\""181		echo ""182		echo "If you do remove this file or comment out this line before"183		echo "proceeding with these tests."184		exit 1185	fi186 187	if diff -q "$FW" /dev/test_firmware >/dev/null ; then188		echo "$0: firmware was not expected to match" >&2189		exit 1190	else191		echo "$0: timeout works"192	fi193}194 195run_sysfs_main_tests()196{197	test_syfs_timeout198	# Put timeout high enough for us to do work but not so long that failures199	# slow down this test too much.200	echo 4 >/sys/class/firmware/timeout201 202	# Load this script instead of the desired firmware.203	load_fw "$NAME" "$0"204	if diff -q "$FW" /dev/test_firmware >/dev/null ; then205		echo "$0: firmware was not expected to match" >&2206		exit 1207	else208		echo "$0: firmware comparison works"209	fi210 211	# Do a proper load, which should work correctly.212	load_fw "$NAME" "$FW"213	if ! diff -q "$FW" /dev/test_firmware >/dev/null ; then214		echo "$0: firmware was not loaded" >&2215		exit 1216	else217		echo "$0: fallback mechanism works"218	fi219 220	load_fw_cancel "nope-$NAME" "$FW"221	if diff -q "$FW" /dev/test_firmware >/dev/null ; then222		echo "$0: firmware was expected to be cancelled" >&2223		exit 1224	else225		echo "$0: cancelling fallback mechanism works"226	fi227 228	set +e229	load_fw_fallback_with_child "nope-signal-$NAME" "$FW"230	if [ "$?" -eq 0 ]; then231		echo "$0: SIGCHLD on sync ignored as expected" >&2232	else233		echo "$0: error - sync firmware request cancelled due to SIGCHLD" >&2234		exit 1235	fi236	set -e237}238 239run_sysfs_custom_load_tests()240{241	RANDOM_FILE_PATH=$(setup_random_file)242	RANDOM_FILE="$(basename $RANDOM_FILE_PATH)"243	if load_fw_custom "$RANDOM_FILE" "$RANDOM_FILE_PATH" ; then244		if ! diff -q "$RANDOM_FILE_PATH" /dev/test_firmware >/dev/null ; then245			echo "$0: firmware was not loaded" >&2246			exit 1247		else248			echo "$0: custom fallback loading mechanism works"249		fi250	fi251 252	RANDOM_FILE_PATH=$(setup_random_file)253	RANDOM_FILE="$(basename $RANDOM_FILE_PATH)"254	if load_fw_custom "$RANDOM_FILE" "$RANDOM_FILE_PATH" ; then255		if ! diff -q "$RANDOM_FILE_PATH" /dev/test_firmware >/dev/null ; then256			echo "$0: firmware was not loaded" >&2257			exit 1258		else259			echo "$0: custom fallback loading mechanism works"260		fi261	fi262 263	RANDOM_FILE_REAL="$RANDOM_FILE_PATH"264	FAKE_RANDOM_FILE_PATH=$(setup_random_file_fake)265	FAKE_RANDOM_FILE="$(basename $FAKE_RANDOM_FILE_PATH)"266 267	if load_fw_custom_cancel "$FAKE_RANDOM_FILE" "$RANDOM_FILE_REAL" ; then268		if diff -q "$RANDOM_FILE_PATH" /dev/test_firmware >/dev/null ; then269			echo "$0: firmware was expected to be cancelled" >&2270			exit 1271		else272			echo "$0: cancelling custom fallback mechanism works"273		fi274	fi275}276 277if [ "$HAS_FW_LOADER_USER_HELPER_FALLBACK" = "yes" ]; then278	run_sysfs_main_tests279fi280 281run_sysfs_custom_load_tests282 283exit 0284