0ad5fbd48d
Instead of hardcoding paths to the executables, use the version in the path. This allows the scripts to work on more systems, and allows the binary version to be changed more easily if needed. Signed-off-by: Martin Roth <martin@coreboot.org> Change-Id: Ifcc56aa21092cd3866eacb6a02d198110ec6051d Reviewed-on: https://review.coreboot.org/c/coreboot/+/48904 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Angel Pons <th3fanbus@gmail.com>
159 lines
4.2 KiB
Bash
Executable file
159 lines
4.2 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
|
|
# SPDX-License-Identifier: GPL-2.0-only
|
|
|
|
LANG=C
|
|
# Some tools emit errors that don't matter (bugs in lspci/PCI firmware and lsusb).
|
|
# To shown them anyway (e.g. for debugging) comment next line.
|
|
exec 2>/dev/null
|
|
|
|
if [ "$1" = "-h" ]; then
|
|
printf "Usage: $0 [-h | path to dmesg log]
|
|
|
|
This script tries to find USB ports compatible with USB2/EHCI debug devices and
|
|
helps you to find their physical locations. To that end, attach at least one
|
|
uniquely identifiable device to a USB port and run this script. The device needs
|
|
to be visible in the output of \"lsusb -t\" (debug devices are often *not*!).
|
|
|
|
After determining compatibility of the USB controllers the script will print the
|
|
devices attached to the debug port as shown by lsusb. If nothing shows up simply
|
|
switch ports and repeat the process.
|
|
|
|
Note: usually only one port is supported for debugging.\n"
|
|
exit 0
|
|
fi
|
|
uid=`id -u`
|
|
if [ "$uid" -ne 0 ]; then
|
|
echo "Must be run as root. Exiting."
|
|
exit 1
|
|
fi
|
|
dmesgfile=$1
|
|
|
|
find_devs_in_tree () {
|
|
bus=$1
|
|
port=$2
|
|
busstr=`printf "Bus %02d" "$bus"`
|
|
portstr="Port $port"
|
|
|
|
hubs_to_ignore="8087:0020 8087:0024"
|
|
reqlvl=1
|
|
|
|
found=
|
|
# Iterate over the output of lsusb -t because it contains the physical port numbers
|
|
while IFS='' read -r line; do
|
|
# We need to keep track of the current bus "branch"
|
|
# Look out for lines starting with /: (that indicate a bus)
|
|
if [ "${line#*/:}" != "$line" ]; then
|
|
if [ "${line#*$busstr}" != "$line" ]; then
|
|
cur_bus=$busstr
|
|
else
|
|
cur_bus=
|
|
fi
|
|
continue
|
|
fi
|
|
|
|
# Skip all lines not belonging to the wanted bus number
|
|
if [ "$cur_bus" != "$busstr" ]; then
|
|
continue
|
|
fi
|
|
|
|
# Calculate current USB tier/level
|
|
spaces="${line%%[!' ']*}"
|
|
curlvl=$((${#spaces} / 4))
|
|
if [ $curlvl -ne $reqlvl ]; then
|
|
continue
|
|
fi
|
|
|
|
# Fetch USB IDs of the current device
|
|
dev=`echo ${line#*Dev } | cut -d ',' -f 1`
|
|
lsusbline=`lsusb -s "$bus":"$dev"`
|
|
if [[ ! "$lsusbline" =~ .*([[:xdigit:]]{4}:[[:xdigit:]]{4}) ]]; then
|
|
printf "Unexpected output from \"%s\": \"%s\"\n" "lsusb -s $bus:$dev" "$usbline"
|
|
exit 1
|
|
fi
|
|
ids=${BASH_REMATCH[1]}
|
|
|
|
# Skip over rate matching hubs
|
|
if [[ "$hubs_to_ignore" == *"$ids"* ]]; then
|
|
((reqlvl += 1))
|
|
continue
|
|
fi
|
|
|
|
# Check for matching physical USB port
|
|
if [ "${line#*$portstr}" != "$line" ]; then
|
|
echo "$lsusbline"
|
|
return
|
|
fi
|
|
done<< EOF
|
|
$(lsusb -t)
|
|
EOF
|
|
if [ -z "$found" ]; then
|
|
echo "none"
|
|
fi
|
|
}
|
|
|
|
debug_lspci_devs=`lspci -nvvD |
|
|
grep -i "^[0-9a-f]\|debug port" |
|
|
grep -iB1 --no-group-separator "debug port" |
|
|
grep -vi "debug port" |
|
|
cut -f 1 -d" " |
|
|
sort |
|
|
xargs echo`
|
|
|
|
if [ -z "$debug_lspci_devs" ]; then
|
|
printf "No USB controller with debug capability found by lspci.\n
|
|
Possible reasons: lspci too old, USB controller does not support a debug device, ... Exiting.\n"
|
|
exit 1
|
|
fi
|
|
printf "The following PCI devices support a USB debug port (says lspci): $debug_lspci_devs\n"
|
|
|
|
debug_dmesg_devs_with_port=`( test -z "$dmesgfile" &&
|
|
dmesg ||
|
|
cat "$dmesgfile") |
|
|
grep -i "ehci.*debug port" |
|
|
sed "s/.* \([0-9a-f]*:*[0-9a-f]\{2\}:[0-9a-f]\{2\}\.[0-9a-f]\).*ebug port /\1 /" |
|
|
sort`
|
|
|
|
debug_dmesg_devs=`echo "$debug_dmesg_devs_with_port" |
|
|
cut -f 1 -d" " |
|
|
xargs echo`
|
|
|
|
if [ -z "$debug_dmesg_devs" ]; then
|
|
printf "dmesg does not show any supported ports.\n
|
|
Possible reasons: dmesg scrolled off, kernel too old, USB controller does not support a debug device, ... Exiting.\n
|
|
Note: You can specify a file containing kernel messages as an argument to this program (e.g. /var/log/dmesg)."
|
|
exit 1
|
|
fi
|
|
|
|
if [ "$debug_lspci_devs" != "$debug_dmesg_devs" ]; then
|
|
echo "lspci and the kernel do not agree on USB debug device support. Exiting."
|
|
exit 1
|
|
fi
|
|
|
|
printf "and the kernel agrees, good.\n\n"
|
|
|
|
while true; do
|
|
for dev in $debug_dmesg_devs; do
|
|
bus=`lsusb -v |
|
|
grep "^Bus\|iSerial.*" |
|
|
grep -B1 --no-group-separator "iSerial.*$dev" |
|
|
grep "^Bus" |
|
|
sed "s/Bus *0*\([0-9a-f]*\).*/\1/"`
|
|
port=`echo "$debug_dmesg_devs_with_port" |
|
|
grep "^$dev" |
|
|
cut -f 2 -d" "`
|
|
|
|
echo "Device(s) currently connected to the debug-capable port $port on PCI device $dev, USB bus $bus:"
|
|
|
|
find_devs_in_tree "$bus" "$port"
|
|
echo
|
|
done
|
|
|
|
echo "Enter 'q' to abort or anything else to repeat"
|
|
read -r r
|
|
if [ $? -ne 0 -o "$r" = "q" ]; then
|
|
break;
|
|
fi
|
|
done
|
|
|
|
exit 0
|