#!/bin/bash

###############################################################################
#
# lsvfio: lsuio equivalent for vfiouser devices
#

for _dev in /dev/vfio/*@*:*:*\.*; do

    [ -h ${_dev} ] || continue

    _pci_dev="${_dev#*@}"

    # show the PCI device
    _pci_desc=$(lspci -s ${_pci_dev})
    [ -z "${_pci_desc}" ] && continue
    echo ${_pci_desc}

    # collect the IRQs assigned to the device
    _dev_dir="/sys/bus/pci/devices/${_pci_dev}"
    if [ -d ${_dev_dir}/msi_irqs ]; then
       _irqs=${_dev_dir}/msi_irqs/*
    else
        _irqs=$(cat ${_dev_dir}/irq 2>/dev/null)
    fi

    # show the IRQ count(s)
    for _irq in ${_irqs}; do
        _irq=${_irq##*/}
        _irql=$(grep -o "^ *${_irq}:[ 0-9]*" /proc/interrupts)
        _count=0
        for _i in ${_irql#*:}; do _count=$((${_count}+${_i})); done
        echo "	IRQ ${_irq}: ${_count}"
    done

    # show the memory regions
    while read _bar; do
          echo "	${_bar/Memory at/Bus address:}"
          _bar=${_bar#* at }
          _bar=${_bar%% *}
          # and the user-space mappings
          while read -a _map; do
                echo "	${_map[@]/maps:/maps: }"
          done < <(grep -H " ${_bar} .*vfio-device" /proc/*/maps 2>/dev/null)
    done < <(lspci -vs ${_pci_dev} | grep "^	Memory at")

    echo

done
