#include #include #include #include #include "evga-card.h" #include "icx3.h" /* 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); num_gpus++; break; } } } if (num_gpus == max_gpus) break; } return num_gpus; }