Skip to content

Instantly share code, notes, and snippets.

@r15ch13
Last active July 23, 2024 00:52
Show Gist options
  • Save r15ch13/ba2d738985fce8990a4e9f32d07c6ada to your computer and use it in GitHub Desktop.
Save r15ch13/ba2d738985fce8990a4e9f32d07c6ada to your computer and use it in GitHub Desktop.
List IOMMU Groups and the connected USB Devices
#!/usr/bin/env bash
shopt -s nullglob
lastgroup=""
for g in `find /sys/kernel/iommu_groups/* -maxdepth 0 -type d | sort -V`; do
for d in $g/devices/*; do
if [ "${g##*/}" != "$lastgroup" ]; then
echo -en "Group ${g##*/}:\t"
else
echo -en "\t\t"
fi
lastgroup=${g##*/}
lspci -nms ${d##*/} | awk -F'"' '{printf "[%s:%s]", $4, $6}'
if [[ -e "$d"/reset ]]; then echo -en " [R] "; else echo -en " "; fi
lspci -mms ${d##*/} | awk -F'"' '{printf "%s %-40s %s\n", $1, $2, $6}'
for u in ${d}/usb*/; do
bus=$(cat "${u}/busnum")
lsusb -s $bus: | \
awk '{gsub(/:/,"",$4); printf "%s|%s %s %s %s|", $6, $1, $2, $3, $4; for(i=7;i<=NF;i++){printf "%s ", $i}; printf "\n"}' | \
awk -F'|' '{printf "USB:\t\t[%s]\t\t %-40s %s\n", $1, $2, $3}'
done
done
done
@digitalformula
Copy link

@digitalformula yeah something like this (quick hack):

iommu group 15:
02:00.0 Network controller [0280]: Intel Corporation Wi-Fi 6E(802.11ax) AX210/AX1675* 2x2 [Typhoon Peak] [8086:2725] (rev 1a)
net:    wlp2s0  mac ff:ff:ff:ff:ff:ff

I adapted this script a bit to be posix shell and only what I need, but this is what I abuse:

cur=''
for dir in $(find /sys/kernel/iommu_groups/ -type l | sort -n -k5 -t/); do
  iommu=${dir#*/iommu_groups/*}
  iommu=${iommu%%/*}
  if [ "${iommu}" != "${cur}" ]; then
    printf 'iommu group %s:\n' "${iommu}"
    cur="${iommu}"
  fi

  lspci -nns "${dir##*/}"

  for usb in ${dir}/usb*/; do
    if [ -e "${usb}/busnum" ]; then
      bus=$(cat "${usb}/busnum")
      lsusb -s "${bus}": \
        | awk '{gsub(/:/,"",$4); printf "%s|%s %s %s %s|", $6, $1, $2, $3, $4; for(i=7;i<=NF;i++){printf "%s ", $i}; printf "\n"}' \
        | awk -F'|' '{printf "usb:\t[%s]\t %-40s %s\n", $1, $2, $3}'
    fi
  done

  for net in ${dir}/net/*; do
    if [ -e "${net}/address" ]; then
      name=$(basename "${net}")
      mac=$(cat "${net}/address")
      printf "net:\t%s\tmac %s\n" "${name}" "${mac}"
    fi
  done
done

You could snag more stuff out of the device tree but device name/mac is a decent enough start.

Brilliant, thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment