| #!/bin/bash |
| |
| uio_drivers="igb_uio uio_pci_generic vfio-pci" |
| tmpfile=$(mktemp) |
| |
| |
| function bind_drv() { |
| addr=$1 |
| modalias=$(cat $selection/modalias) |
| native_drv=$(modprobe -R $modalias) |
| array=() |
| |
| for drv in $native_drv $uio_drivers; do |
| if [ -e /sys/bus/pci/drivers/$drv ]; then |
| echo driver $drv |
| drv_desc=$(modinfo $drv | grep description: | sed -e 's/.*:[[:space:]]\+//' ) |
| array+=("${drv}") |
| array+=("${drv_desc}") |
| fi |
| done |
| dialog --backtitle "PCI NIC Bind Utility" \ |
| --clear \ |
| --menu "Select kernel driver" 18 100 12 \ |
| "${array[@]}" 2> $tmpfile |
| retval=$? |
| selection=$(cat $tmpfile) |
| rm $tmpfile |
| if [ $retval -ne 0 ]; then |
| return |
| fi |
| vd=$(cat /sys/bus/pci/devices/${addr}/vendor /sys/bus/pci/devices/${addr}/device) |
| echo $addr | tee /sys/bus/pci/devices/${addr}/driver/unbind > /dev/null 2> /dev/null |
| echo $vd | tee /sys/bus/pci/drivers/${selection}/new_id > /dev/null 2> /dev/null |
| echo $addr | tee /sys/bus/pci/drivers/${selection}/bind > /dev/null 2> /dev/null |
| } |
| |
| function find_pci_slot() { |
| addr=$1 |
| [ ! "$(ls -A /sys/bus/pci/slots )" ] && echo "No PCI slot data" && return |
| for slot in $(find /sys/bus/pci/slots/* -maxdepth 0 -exec basename {} \;); do |
| slot_addr=$(cat /sys/bus/pci/slots/$slot/address) |
| if [[ "${addr}" == *"${slot_addr}"* ]]; then |
| echo "PCI slot: ${slot}" |
| return |
| fi |
| done |
| echo "Unknown PCI slot" |
| } |
| |
| ! type -ap dialog > /dev/null && echo "Please install dialog (apt-get install dialog)" && exit |
| if [ $USER != "root" ] ; then |
| echo "Restarting script with sudo..." |
| sudo $0 ${*} |
| exit |
| fi |
| |
| cd /sys/bus/pci/devices |
| |
| while true; do |
| array=() |
| for addr in *; do |
| class=$(cat ${addr}/class) |
| if [ "$class" = "0x020000" ]; then |
| name=$(lspci -s $addr | sed -e 's/.*: //') |
| if [ -e "/sys/bus/pci/devices/$addr/driver" ]; then |
| drv=$(basename $(readlink -f /sys/bus/pci/devices/$addr/driver)) |
| else |
| drv=" " |
| fi |
| slot=$(find_pci_slot ${addr}) |
| array+=("${addr}") |
| array+=("${drv}|${name}") |
| array+=("${slot}") |
| fi |
| done |
| |
| dialog --backtitle "PCI NIC Bind Utility" \ |
| --item-help \ |
| --clear \ |
| --column-separator '|' \ |
| --menu "Select NIC" 18 100 12 \ |
| "${array[@]}" 2> $tmpfile |
| |
| retval=$? |
| selection=$(cat $tmpfile) |
| rm $tmpfile |
| if [ $retval -ne 0 ]; then |
| exit |
| fi |
| bind_drv $selection |
| done |
| |
| |
| |