#!/bin/bash

# Copyright (C) 2013-2025 Marcin Krol <hawk@tld-linux.org>
# All Rights Reserved

find_modules () {
  modalias_file="$1"
  shift
  device_classes="$@"
  echo "" | awk '
    {
      i=0
      while("cat /sys/bus/pci/devices/*/modalias" | getline) {
        aliases[i]=tolower($1)
        i++
      }
      nclasses=split("'"${device_classes}"'", classes, " ")
      while(getline < "'"${modalias_file}"'") {
        if($1 == "alias" && match($2, "^pci:")) {
          regex = tolower($2)
          gsub(/\*/, ".*", regex)
          for (a in aliases) {
            if(match(aliases[a],regex)) {
              if(nclasses == 0) { print $3 }
              else {
                for(c in classes) {
                  cregex = tolower(".*bc" substr(classes[c],1,2) "sc" substr(classes[c],3,2) "i.*")
                  if(match(aliases[a],cregex)) { print $3 }
                }
              }
            }
          }
        }
      }
    }
  '
}

is_modalias_file () {
  if [ -z "${1}" ]; then
    return 0
  fi
  if [ -f "${1}" ]; then
    if grep -q -E "^alias pci" "${1}"; then
      return 1
    fi
  fi
  return 0
}

if [ $# -ge 1 ]; then
  is_modalias_file "${1}"
  result=$?
  if [ "${result}" -eq 1 ]; then
    modalias_file="${1}"
  else
    modalias_file="/lib/modules/$(uname -r 2>/dev/null)/modules.alias"
  fi
else
  modalias_file="/lib/modules/$(uname -r 2>/dev/null)/modules.alias"
fi

is_modalias_file "${modalias_file}"
result=$?
if [ "${result}" -eq 1 ]; then
  find_modules "${modalias_file}" $@ | sort -u
fi
