#include #include #include #include #include "evga-card.h" #include "icx3.h" struct gpu_pci_info { char *card_name; unsigned short vendor_id; unsigned short device_id; unsigned short subvendor_id; unsigned short subdevice_id; }; static struct gpu_pci_info evga_pci_ids[] = { {"EVGA GeForce RTX 3060 Ti FTW3 Gaming" , NVIDIA_VEN, NVIDIA_RTX3060TI_DEV, EVGA_SUB_VEN, EVGA_RTX3060TI_FTW3_GAMING_SUB_DEV }, {"EVGA GeForce RTX 3060 Ti FTW3 Ultra" , NVIDIA_VEN, NVIDIA_RTX3060TI_DEV, EVGA_SUB_VEN, EVGA_RTX3060TI_FTW3_ULTRA_SUB_DEV }, {"EVGA GeForce RTX 3060 Ti FTW3 Ultra LHR" , NVIDIA_VEN, NVIDIA_RTX3060TI_LHR_DEV, EVGA_SUB_VEN, EVGA_RTX3060TI_FTW3_ULTRA_KL_SUB_DEV }, {"EVGA GeForce RTX 3070 Black Gaming" , NVIDIA_VEN, NVIDIA_RTX3070_DEV, EVGA_SUB_VEN, EVGA_RTX3070_XC3_BLACK_SUB_DEV }, {"EVGA GeForce RTX 3070 XC3 Gaming" , NVIDIA_VEN, NVIDIA_RTX3070_DEV, EVGA_SUB_VEN, EVGA_RTX3070_XC3_GAMING_SUB_DEV }, {"EVGA GeForce RTX 3070 XC3 Ultra" , NVIDIA_VEN, NVIDIA_RTX3070_DEV, EVGA_SUB_VEN, EVGA_RTX3070_XC3_ULTRA_SUB_DEV }, {"EVGA GeForce RTX 3070 XC3 Ultra LHR" , NVIDIA_VEN, NVIDIA_RTX3070_LHR_DEV, EVGA_SUB_VEN, EVGA_RTX3070_XC3_ULTRA_LHR_SUB_DEV }, {"EVGA GeForce RTX 3070 XC3 Ultra Gaming" , NVIDIA_VEN, NVIDIA_RTX3070_LHR_DEV, EVGA_SUB_VEN, EVGA_RTX3070_XC3_ULTRA_GAMING_LHR_SUB_DEV }, {"EVGA GeForce RTX 3070 FTW3 Ultra" , NVIDIA_VEN, NVIDIA_RTX3070_DEV, EVGA_SUB_VEN, EVGA_RTX3070_FTW3_ULTRA_SUB_DEV }, {"EVGA GeForce RTX 3070 FTW3 Ultra LHR" , NVIDIA_VEN, NVIDIA_RTX3070_LHR_DEV, EVGA_SUB_VEN, EVGA_RTX3070_FTW3_ULTRA_LHR_SUB_DEV }, {"EVGA GeForce RTX 3070 Ti XC3 Gaming" , NVIDIA_VEN, NVIDIA_RTX3070TI_DEV, EVGA_SUB_VEN, EVGA_RTX3070TI_XC3_GAMING_SUB_DEV }, {"EVGA GeForce RTX 3070 Ti XC3 Ultra" , NVIDIA_VEN, NVIDIA_RTX3070TI_DEV, EVGA_SUB_VEN, EVGA_RTX3070TI_XC3_ULTRA_SUB_DEV }, {"EVGA GeForce RTX 3070 Ti XC3 Ultra v2" , NVIDIA_VEN, NVIDIA_RTX3070TI_DEV, EVGA_SUB_VEN, EVGA_RTX3070TI_XC3_ULTRA_V2_SUB_DEV }, {"EVGA GeForce RTX 3070 Ti FTW3 Ultra" , NVIDIA_VEN, NVIDIA_RTX3070TI_DEV, EVGA_SUB_VEN, EVGA_RTX3070TI_FTW3_ULTRA_SUB_DEV }, {"EVGA GeForce RTX 3070 Ti FTW3 Ultra v2" , NVIDIA_VEN, NVIDIA_RTX3070TI_DEV, EVGA_SUB_VEN, EVGA_RTX3070TI_FTW3_ULTRA_V2_SUB_DEV }, {"EVGA GeForce RTX 3080 XC3 Black" , NVIDIA_VEN, NVIDIA_RTX3080_DEV, EVGA_SUB_VEN, EVGA_RTX3080_XC3_BLACK_SUB_DEV }, {"EVGA GeForce RTX 3080 XC3 Black LHR" , NVIDIA_VEN, NVIDIA_RTX3080_LHR_DEV, EVGA_SUB_VEN, EVGA_RTX3080_XC3_BLACK_LHR_SUB_DEV }, {"EVGA GeForce RTX 3080 XC3 Gaming" , NVIDIA_VEN, NVIDIA_RTX3080_DEV, EVGA_SUB_VEN, EVGA_RTX3080_XC3_GAMING_SUB_DEV }, {"EVGA GeForce RTX 3080 XC3 Gaming LHR" , NVIDIA_VEN, NVIDIA_RTX3080_LHR_DEV, EVGA_SUB_VEN, EVGA_RTX3080_XC3_GAMING_LHR_SUB_DEV }, {"EVGA GeForce RTX 3080 XC3 Ultra" , NVIDIA_VEN, NVIDIA_RTX3080_DEV, EVGA_SUB_VEN, EVGA_RTX3080_XC3_ULTRA_SUB_DEV }, {"EVGA GeForce RTX 3080 XC3 Ultra LHR" , NVIDIA_VEN, NVIDIA_RTX3080_LHR_DEV, EVGA_SUB_VEN, EVGA_RTX3080_XC3_ULTRA_LHR_SUB_DEV }, {"EVGA GeForce RTX 3080 XC3 Ultra Hybrid" , NVIDIA_VEN, NVIDIA_RTX3080_DEV, EVGA_SUB_VEN, EVGA_RTX3080_XC3_ULTRA_HYBRID_SUB_DEV }, {"EVGA GeForce RTX 3080 XC3 Ultra Hybrid LHR" , NVIDIA_VEN, NVIDIA_RTX3080_LHR_DEV, EVGA_SUB_VEN, EVGA_RTX3080_XC3_ULTRA_HYBRID_LHR_SUB_DEV }, {"EVGA GeForce RTX 3080 XC3 Ultra Hydro Copper" , NVIDIA_VEN, NVIDIA_RTX3080_DEV, EVGA_SUB_VEN, EVGA_RTX3080_XC3_ULTRA_HC_SUB_DEV }, {"EVGA GeForce RTX 3080 FTW3 Gaming" , NVIDIA_VEN, NVIDIA_RTX3080_DEV, EVGA_SUB_VEN, EVGA_RTX3080_FTW3_GAMING_SUB_DEV }, {"EVGA GeForce RTX 3080 FTW3 Ultra" , NVIDIA_VEN, NVIDIA_RTX3080_DEV, EVGA_SUB_VEN, EVGA_RTX3080_FTW3_ULTRA_SUB_DEV }, {"EVGA GeForce RTX 3080 FTW3 Ultra v2 LHR" , NVIDIA_VEN, NVIDIA_RTX3080_LHR_DEV, EVGA_SUB_VEN, EVGA_RTX3080_FTW3_ULTRA_LHR_V2_SUB_DEV }, {"EVGA GeForce RTX 3080 FTW3 Ultra LHR" , NVIDIA_VEN, NVIDIA_RTX3080_LHR_DEV, EVGA_SUB_VEN, EVGA_RTX3080_FTW3_ULTRA_LHR_SUB_DEV }, {"EVGA GeForce RTX 3080 FTW3 Ultra Hybrid" , NVIDIA_VEN, NVIDIA_RTX3080_DEV, EVGA_SUB_VEN, EVGA_RTX3080_FTW3_ULTRA_HYBRID_SUB_DEV }, {"EVGA GeForce RTX 3080 FTW3 Ultra Hybrid LHR" , NVIDIA_VEN, NVIDIA_RTX3080_LHR_DEV, EVGA_SUB_VEN, EVGA_RTX3080_FTW3_ULTRA_HYBRID_LHR_SUB_DEV }, {"EVGA GeForce RTX 3080 FTW3 Ultra Hybrid Gaming LHR" , NVIDIA_VEN, NVIDIA_RTX3080_12G_LHR_DEV, EVGA_SUB_VEN, EVGA_RTX3080_FTW3_ULTRA_HYBRID_GAMING_SUB_DEV }, {"EVGA GeForce RTX 3080 FTW3 Ultra Hydro Copper" , NVIDIA_VEN, NVIDIA_RTX3080_DEV, EVGA_SUB_VEN, EVGA_RTX3080_FTW3_ULTRA_HC_SUB_DEV }, {"EVGA GeForce RTX 3080 XC3 Ultra 12G" , NVIDIA_VEN, NVIDIA_RTX3080_12G_LHR_DEV, EVGA_SUB_VEN, EVGA_RTX3080_12G_XC3_ULTRA_SUB_DEV }, {"EVGA GeForce RTX 3080 FTW3 Ultra 12GB" , NVIDIA_VEN, NVIDIA_RTX3080_12G_LHR_DEV, EVGA_SUB_VEN, EVGA_RTX3080_12G_FTW3_ULTRA_SUB_DEV }, {"EVGA GeForce RTX 3080 FTW3 Ultra Hydro Copper 12G" , NVIDIA_VEN, NVIDIA_RTX3080_12G_LHR_DEV, EVGA_SUB_VEN, EVGA_RTX3080_12G_FTW3_ULTRA_HC_SUB_DEV }, {"EVGA GeForce RTX 3080 Ti XC3 Gaming" , NVIDIA_VEN, NVIDIA_RTX3080TI_DEV, EVGA_SUB_VEN, EVGA_RTX3080TI_XC3_GAMING_SUB_DEV }, {"EVGA GeForce RTX 3080 Ti XC3 Ultra Gaming" , NVIDIA_VEN, NVIDIA_RTX3080TI_DEV, EVGA_SUB_VEN, EVGA_RTX3080TI_XC3_ULTRA_GAMING_SUB_DEV }, {"EVGA GeForce RTX 3080 Ti XC3 Gaming Hybrid" , NVIDIA_VEN, NVIDIA_RTX3080TI_DEV, EVGA_SUB_VEN, EVGA_RTX3080TI_XC3_GAMING_HYBRID_SUB_DEV }, {"EVGA GeForce RTX 3080 Ti XC3 Gaming Hydro Copper" , NVIDIA_VEN, NVIDIA_RTX3080TI_DEV, EVGA_SUB_VEN, EVGA_RTX3080TI_XC3_GAMING_HC_SUB_DEV }, {"EVGA GeForce RTX 3080 Ti FTW3 Ultra" , NVIDIA_VEN, NVIDIA_RTX3080TI_DEV, EVGA_SUB_VEN, EVGA_RTX3080TI_FTW3_ULTRA_SUB_DEV }, {"EVGA GeForce RTX 3080 Ti FTW3 Ultra Hybrid" , NVIDIA_VEN, NVIDIA_RTX3080TI_DEV, EVGA_SUB_VEN, EVGA_RTX3080TI_FTW3_ULTRA_HYBRID_SUB_DEV }, {"EVGA GeForce RTX 3080 Ti FTW3 Ultra Hydro Copper" , NVIDIA_VEN, NVIDIA_RTX3080TI_DEV, EVGA_SUB_VEN, EVGA_RTX3080TI_FTW3_ULTRA_HC_SUB_DEV }, {"EVGA GeForce RTX 3090 XC3 Black" , NVIDIA_VEN, NVIDIA_RTX3090_DEV, EVGA_SUB_VEN, EVGA_RTX3090_XC3_BLACK_SUB_DEV }, {"EVGA GeForce RTX 3090 XC3 Gaming" , NVIDIA_VEN, NVIDIA_RTX3090_DEV, EVGA_SUB_VEN, EVGA_RTX3090_XC3_GAMING_SUB_DEV }, {"EVGA GeForce RTX 3090 XC3 Ultra" , NVIDIA_VEN, NVIDIA_RTX3090_DEV, EVGA_SUB_VEN, EVGA_RTX3090_XC3_ULTRA_SUB_DEV }, {"EVGA GeForce RTX 3090 XC3 Ultra Hybrid" , NVIDIA_VEN, NVIDIA_RTX3090_DEV, EVGA_SUB_VEN, EVGA_RTX3090_XC3_ULTRA_HYBRID_SUB_DEV }, {"EVGA GeForce RTX 3090 XC3 Ultra Hydro Copper" , NVIDIA_VEN, NVIDIA_RTX3090_DEV, EVGA_SUB_VEN, EVGA_RTX3090_XC3_ULTRA_HC_SUB_DEV }, {"EVGA GeForce RTX 3090 FTW3 Ultra" , NVIDIA_VEN, NVIDIA_RTX3090_DEV, EVGA_SUB_VEN, EVGA_RTX3090_FTW3_ULTRA_SUB_DEV }, {"EVGA GeForce RTX 3090 FTW3 Ultra v2" , NVIDIA_VEN, NVIDIA_RTX3090_DEV, EVGA_SUB_VEN, EVGA_RTX3090_FTW3_ULTRA_V2_SUB_DEV }, {"EVGA GeForce RTX 3090 FTW3 Ultra v3" , NVIDIA_VEN, NVIDIA_RTX3090_DEV, EVGA_SUB_VEN, EVGA_RTX3090_FTW3_ULTRA_V3_SUB_DEV }, {"EVGA GeForce RTX 3090 FTW3 Ultra Hybrid" , NVIDIA_VEN, NVIDIA_RTX3090_DEV, EVGA_SUB_VEN, EVGA_RTX3090_FTW3_ULTRA_HYBRID_SUB_DEV }, {"EVGA GeForce RTX 3090 FTW3 Ultra Hydro Copper" , NVIDIA_VEN, NVIDIA_RTX3090_DEV, EVGA_SUB_VEN, EVGA_RTX3090_FTW3_ULTRA_HC_SUB_DEV }, {"EVGA GeForce RTX 3090 K|NGP|N Hybrid" , NVIDIA_VEN, NVIDIA_RTX3090_DEV, EVGA_SUB_VEN, EVGA_RTX3090_KINGPIN_HYBRID_SUB_DEV }, {"EVGA GeForce RTX 3090 K|NGP|N Hydro Copper" , NVIDIA_VEN, NVIDIA_RTX3090_DEV, EVGA_SUB_VEN, EVGA_RTX3090_KINGPIN_HC_SUB_DEV }, {"EVGA GeForce RTX 3090 Ti FTW3 Black Gaming" , NVIDIA_VEN, NVIDIA_RTX3090TI_DEV, EVGA_SUB_VEN, EVGA_RTX3090TI_FTW3_BLACK_SUB_DEV }, {"EVGA GeForce RTX 3090 Ti FTW3 Gaming" , NVIDIA_VEN, NVIDIA_RTX3090TI_DEV, EVGA_SUB_VEN, EVGA_RTX3090TI_FTW3_GAMING_SUB_DEV }, {"EVGA GeForce RTX 3090 Ti FTW3 Ultra Gaming" , NVIDIA_VEN, NVIDIA_RTX3090TI_DEV, EVGA_SUB_VEN, EVGA_RTX3090TI_FTW3_ULTRA_GAMING_SUB_DEV } }; /* Search all i2c device files for ones are on a PCI device of a supported GPU, and respond with the correct iCX3 version information */ int find_evga_gpu_i2cs(struct card_info *infos, int max_gpus, int i2c_bus) { char i2c_devices_path[PATH_MAX]; char device_path[PATH_MAX]; char dev_file[PATH_MAX]; char pci_path[PATH_MAX]; char *pci_addr; FILE *test_fd; DIR *dir; struct dirent *ent; int num_gpus = 0; int current_i2c_bus = -1; unsigned short pci_vendor, pci_device, pci_subsystem_vendor, pci_subsystem_device = 0; /* Start looking for I2C adapters in /sys/bus/i2c/devices/ */ strcpy(i2c_devices_path, "/sys/bus/i2c/devices/"); dir = opendir(i2c_devices_path); /* make sure we can open the i2c device */ if(dir == NULL) return -1; /* loop over all i2c devices */ while((ent = readdir(dir)) != NULL) { /* Don't check any non-i2c devices */ if(strncmp(ent->d_name, "i2c-", 4) != 0) continue; /* Only probe the specific device given (if provided) */ if (i2c_bus >= 0) { sscanf(ent->d_name, "i2c-%i", ¤t_i2c_bus); if (current_i2c_bus != i2c_bus) continue; } strcpy(device_path, i2c_devices_path); strcat(device_path, ent->d_name); /* Only check Nvidia devices */ pci_addr = read_nvidia_pci_address(device_path); if (pci_addr == NULL) continue; /* Read the PCI info for the underlying device */ strcat(device_path, "/../"); if (realpath(device_path, pci_path) == NULL) continue; pci_vendor = read_pci_id(pci_path, "/vendor"); pci_device = read_pci_id(pci_path, "/device"); pci_subsystem_vendor = read_pci_id(pci_path, "/subsystem_vendor"); pci_subsystem_device = read_pci_id(pci_path, "/subsystem_device"); /* See if it's a matching device for a supported EVGA card */ for (int i = 0; i < (sizeof(evga_pci_ids) / sizeof(struct gpu_pci_info)); i++) { if (pci_vendor == evga_pci_ids[i].vendor_id && pci_device == evga_pci_ids[i].device_id && pci_subsystem_vendor == evga_pci_ids[i].subvendor_id && pci_subsystem_device == evga_pci_ids[i].subdevice_id) { /* Matched all PCI IDs, check for good firmware read */ strcpy(dev_file, "/dev/"); strcat(dev_file, ent->d_name); infos[num_gpus].i2c_dev_path = dev_file; if (icx3_init(&infos[num_gpus]) > 0) { /* Write our card info into the provided struct array */ infos[num_gpus].card_name = evga_pci_ids[i].card_name; infos[num_gpus].pci_id = pci_addr; infos[num_gpus].pci_dev_path = strdup(pci_path); infos[num_gpus].pci_device_id = pci_device; infos[num_gpus].i2c_dev_path = strdup(dev_file); mmap_bar0(&infos[num_gpus]); num_gpus++; break; } } } if (num_gpus == max_gpus) break; } return num_gpus; }