All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Nícolas F. R. A. Prado" <nfraprado@collabora.com>
To: Shuah Khan <shuah@kernel.org>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Bjorn Helgaas <bhelgaas@google.com>
Cc: devicetree@vger.kernel.org, linux-pci@vger.kernel.org,
	linux-usb@vger.kernel.org, "Rob Herring" <robh+dt@kernel.org>,
	linux-kselftest@vger.kernel.org, kernel@collabora.com,
	"Nícolas F. R. A. Prado" <nfraprado@collabora.com>,
	linux-kernel@vger.kernel.org
Subject: [RFC PATCH 1/2] kselftest: Add test to verify probe of devices from discoverable busses
Date: Tue, 24 Oct 2023 17:17:59 -0400	[thread overview]
Message-ID: <20231024211818.365844-2-nfraprado@collabora.com> (raw)
In-Reply-To: <20231024211818.365844-1-nfraprado@collabora.com>

Add a new test to verify that all expected devices from discoverable
busses (ie USB, PCI) on a given Devicetree-based platform have been
successfully instantiated and probed by a driver.

The per-platform list of expected devices is selected based on
compatible and stored under the boards/ directory.

The tests encode the devices to test for based on the hardware topology.
For USB devices, the format is:
usb <test_name> <controller_address>[,<additional_match>] <ports_path> <configuration> <interfaces>

The additional match field is optional and used to differentiate between
two busses (USB2 and USB3) sharing the same USB host controller.

For PCI devices, the format is:
pci <test_name> <controller_address> <device-function_pairs_path>

Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>

---

 tools/testing/selftests/Makefile              |   1 +
 tools/testing/selftests/devices/.gitignore    |   1 +
 tools/testing/selftests/devices/Makefile      |   8 +
 .../devices/test_discoverable_devices.sh      | 165 ++++++++++++++++++
 4 files changed, 175 insertions(+)
 create mode 100644 tools/testing/selftests/devices/.gitignore
 create mode 100644 tools/testing/selftests/devices/Makefile
 create mode 100755 tools/testing/selftests/devices/test_discoverable_devices.sh

diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index 3b2061d1c1a5..7f5088006c3c 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -13,6 +13,7 @@ TARGETS += core
 TARGETS += cpufreq
 TARGETS += cpu-hotplug
 TARGETS += damon
+TARGETS += devices
 TARGETS += dmabuf-heaps
 TARGETS += drivers/dma-buf
 TARGETS += drivers/s390x/uvdevice
diff --git a/tools/testing/selftests/devices/.gitignore b/tools/testing/selftests/devices/.gitignore
new file mode 100644
index 000000000000..e3c5c04d1b19
--- /dev/null
+++ b/tools/testing/selftests/devices/.gitignore
@@ -0,0 +1 @@
+ktap_helpers.sh
diff --git a/tools/testing/selftests/devices/Makefile b/tools/testing/selftests/devices/Makefile
new file mode 100644
index 000000000000..ff2fdc8fc5e2
--- /dev/null
+++ b/tools/testing/selftests/devices/Makefile
@@ -0,0 +1,8 @@
+TEST_PROGS := test_discoverable_devices.sh
+TEST_GEN_FILES := ktap_helpers.sh
+TEST_FILES := boards
+
+include ../lib.mk
+
+$(OUTPUT)/ktap_helpers.sh:
+	cp ../dt/ktap_helpers.sh $@
diff --git a/tools/testing/selftests/devices/test_discoverable_devices.sh b/tools/testing/selftests/devices/test_discoverable_devices.sh
new file mode 100755
index 000000000000..91842b0c769f
--- /dev/null
+++ b/tools/testing/selftests/devices/test_discoverable_devices.sh
@@ -0,0 +1,165 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+#
+# Copyright (c) 2023 Collabora Ltd
+#
+# This script tests for presence and driver binding of devices from discoverable
+# busses (ie USB, PCI) on Devicetree-based platforms.
+#
+# The per-platform list of devices to be tested is stored inside the boards/
+# directory and chosen based on compatible.
+#
+
+DIR="$(dirname "$(readlink -f "$0")")"
+
+source "${DIR}"/ktap_helpers.sh
+
+KSFT_FAIL=1
+KSFT_SKIP=4
+
+retval=0
+
+usb()
+{
+	name="$1"
+	controller="$2"
+	path="$3"
+	configuration="$4"
+	interfaces="$5"
+
+	# Extract additional match if present
+	if [[ "$controller" =~ , ]]; then
+		additional_match=${controller#*,}
+		address=${controller%,*}
+	else
+		address="$controller"
+	fi
+
+	for controller_uevent in /sys/bus/usb/devices/usb*/uevent; do
+		if grep -q "OF_FULLNAME=.*@$address$" "$controller_uevent"; then
+			# Look for additional match if present. It is needed to
+			# disambiguate two USB busses that share the same
+			# controller.
+			if [ -n "$additional_match" ]; then
+				if ! grep -q "$additional_match" "$controller_uevent"; then
+					continue
+				fi
+			fi
+			dir=$(basename "$(dirname "$controller_uevent")")
+			busnum=${dir#usb}
+		fi
+	done
+
+	usbdevs=/sys/bus/usb/devices/
+
+	IFS=,
+	for intf in $interfaces; do
+		devfile="$busnum"-"$path":"$configuration"."$intf"
+
+		if [ -d "$usbdevs"/"$devfile" ]; then
+			ktap_test_pass usb."$name"."$intf".device
+		else
+			ktap_test_fail usb."$name"."$intf".device
+			retval=$KSFT_FAIL
+		fi
+
+		if [ -d "$usbdevs"/"$devfile"/driver ]; then
+			ktap_test_pass usb."$name"."$intf".driver
+		else
+			ktap_test_fail usb."$name"."$intf".driver
+			retval=$KSFT_FAIL
+		fi
+	done
+}
+
+pci()
+{
+	name="$1"
+	controller="$2"
+	path="$3"
+
+	IFS=$'\n'
+	while read -r uevent; do
+		grep -q "OF_FULLNAME=.*@$controller$" "$uevent" || continue
+
+		# Ignore PCI bus directory, since it will have the same backing
+		# OF node, but not the PCI devices as subdirectories.
+		[[ "$uevent" =~ pci_bus ]] && continue
+
+		host_dir=$(dirname "$uevent")
+	done < <(find /sys/devices -name uevent)
+
+	# Add * to each level of the PCI hierarchy so we can rely on globbing to
+	# find the device directory on sysfs.
+	globbed_path=$(echo "$path" | sed -e 's|^|*|' -e 's|/|/*|')
+	device_path="$host_dir/pci*/$globbed_path"
+
+	# Intentionally left unquoted to allow the glob to expand
+	if [ -d $device_path ]; then
+		ktap_test_pass pci."$name".device
+	else
+		ktap_test_fail pci."$name".device
+		retval=$KSFT_FAIL
+	fi
+
+	if [ -d $device_path/driver ]; then
+		ktap_test_pass pci."$name".driver
+	else
+		ktap_test_fail pci."$name".driver
+		retval=$KSFT_FAIL
+	fi
+}
+
+count_tests()
+{
+	board_file="$1"
+	num_tests=0
+
+	# Each USB interface in a single USB test in the board file is a
+	# separate test
+	while read -r line; do
+		num_intfs=$(echo "$line" | tr -dc , | wc -c)
+		num_intfs=$((num_intfs + 1))
+		num_tests=$((num_tests + num_intfs))
+	done < <(grep ^usb "$board_file" | cut -d ' ' -f 6 -)
+
+	num_pci=$(grep -c ^pci "$board_file")
+	num_tests=$((num_tests + num_pci))
+
+	# Account for device and driver test for each of the tests listed in the
+	# board file.
+	num_tests=$((num_tests * 2))
+	echo $num_tests
+}
+
+ktap_print_header
+
+plat_compatible=/proc/device-tree/compatible
+
+if [ ! -f "$plat_compatible" ]; then
+	ktap_skip_all "No board compatible available"
+	exit "$KSFT_SKIP"
+fi
+
+compatibles=$(tr '\000' '\n' < "$plat_compatible")
+
+for compatible in $compatibles; do
+	if [ -f boards/"$compatible" ]; then
+		board_file=boards/"$compatible"
+		break
+	fi
+done
+
+if [ -z "$board_file" ]; then
+	ktap_skip_all "No matching board file found"
+	exit "$KSFT_SKIP"
+fi
+
+echo "# Using board file: " "$board_file"
+
+ktap_set_plan "$(count_tests "$board_file")"
+
+source "$board_file"
+
+ktap_print_totals
+exit "${retval}"
-- 
2.42.0


  reply	other threads:[~2023-10-24 21:18 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-10-24 21:17 [RFC PATCH 0/2] Add test to verify probe of devices from discoverable busses on DT platforms Nícolas F. R. A. Prado
2023-10-24 21:17 ` Nícolas F. R. A. Prado [this message]
2023-10-24 21:18 ` [RFC PATCH 2/2] kselftest: devices: Add board file for google,spherion Nícolas F. R. A. Prado
2023-10-25 10:32   ` Greg Kroah-Hartman
2023-10-25 12:32     ` Nícolas F. R. A. Prado
2023-10-27 10:48       ` Greg Kroah-Hartman
2023-10-27 20:31         ` Nícolas F. R. A. Prado

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20231024211818.365844-2-nfraprado@collabora.com \
    --to=nfraprado@collabora.com \
    --cc=bhelgaas@google.com \
    --cc=devicetree@vger.kernel.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=kernel@collabora.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=linux-usb@vger.kernel.org \
    --cc=robh+dt@kernel.org \
    --cc=shuah@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.