Added display of fan status and temperature sensors.
This commit is contained in:
+48
-93
@@ -1,18 +1,22 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#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 find_evga_gpu_i2cs(struct card_info *infos, int max_gpus)
|
||||
{
|
||||
char i2c_devices_path[NAME_MAX];
|
||||
char device_path[NAME_MAX];
|
||||
char dev_file[NAME_MAX];
|
||||
|
||||
FILE *test_fd;
|
||||
DIR *dir;
|
||||
struct dirent *ent;
|
||||
|
||||
int num_gpus = 0;
|
||||
unsigned short pci_vendor, pci_device, pci_subsystem_vendor, pci_subsystem_device = 0;
|
||||
@@ -38,114 +42,46 @@ int find_evga_gpu_i2cs(struct card_info **infos, int max_gpus)
|
||||
strcat(device_path, ent->d_name);
|
||||
|
||||
/* Read the PCI info for the underlying device */
|
||||
pci_vendor = read_pci_id(device_path, "/vendor");
|
||||
pci_device = read_pci_id(device_path, "/device");
|
||||
pci_subsystem_vendor = read_pci_id(device_path, "/subsystem_vendor");
|
||||
pci_subsystem_device = read_pci_id(device_path, "/subsystem_device");
|
||||
pci_vendor = read_pci_id(device_path, "/device/vendor");
|
||||
pci_device = read_pci_id(device_path, "/device/device");
|
||||
pci_subsystem_vendor = read_pci_id(device_path, "/device/subsystem_vendor");
|
||||
pci_subsystem_device = read_pci_id(device_path, "/device/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++) {
|
||||
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) {
|
||||
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(device_path, "/dev/");
|
||||
strcat(device_path, ent->d_name);
|
||||
if (check_for_icx3(device_path)) {
|
||||
|
||||
strcpy(dev_file, "/dev/");
|
||||
strcat(dev_file, ent->d_name);
|
||||
if (check_for_icx3(dev_file)) {
|
||||
/* Write our card info into the provided struct array */
|
||||
card_info[num_gpus]->card_name = &evga_pci_ids[i]->card_name;
|
||||
card_info[num_gpus]->pci_id
|
||||
card_info[num_gpus]->i2c_dev_path = calloc(strlen(device_path) + 1, sizeof(char));
|
||||
strcpy(card_info[num_gpus]->i2c_dev_path, device_path);
|
||||
infos[num_gpus].card_name = evga_pci_ids[i].card_name;
|
||||
infos[num_gpus].pci_id = read_nvidia_pci_address(device_path);
|
||||
infos[num_gpus].i2c_dev_path = calloc(strlen(dev_file) + 1, sizeof(char));
|
||||
strcpy(infos[num_gpus].i2c_dev_path, dev_file);
|
||||
num_gpus++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
strcat(device_string, "/name");
|
||||
if (num_gpus == max_gpus)
|
||||
break;
|
||||
|
||||
|
||||
if(strncmp(ent->d_name, "i2c-", 4) == 0)
|
||||
{
|
||||
strcpy(device_string, i2c_devices_path);
|
||||
strcat(device_string, ent->d_name);
|
||||
strcat(device_string, "/name");
|
||||
test_fd = fopen(device_string, O_RDONLY);
|
||||
|
||||
if(test_fd)
|
||||
{
|
||||
memset(device_string, 0x00, sizeof(device_string));
|
||||
|
||||
if(read(test_fd, device_string, sizeof(device_string)) < 0)
|
||||
{
|
||||
printf("Failed to read i2c device name\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
device_string[strlen(device_string) - 1] = 0x00;
|
||||
|
||||
close(test_fd);
|
||||
|
||||
// Clear PCI Information
|
||||
pci_vendor = 0;
|
||||
pci_device = 0;
|
||||
pci_subsystem_vendor = 0;
|
||||
pci_subsystem_device = 0;
|
||||
port_id = 0;
|
||||
|
||||
// Get port ID for NVidia GPUs
|
||||
sscanf(device_string, "NVIDIA i2c adapter %hu at", &port_id);
|
||||
|
||||
// Get device path
|
||||
strcpy(path, i2c_devices_path);
|
||||
strcat(path, ent->d_name);
|
||||
if(ent->d_type == DT_LNK)
|
||||
{
|
||||
ptr = realpath(path, NULL);
|
||||
if(ptr == NULL)
|
||||
continue;
|
||||
|
||||
strcpy(path, ptr);
|
||||
strcat(path, "/..");
|
||||
free(ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
strcat(path, "/device");
|
||||
}
|
||||
ptr = path + strlen(path);
|
||||
|
||||
|
||||
|
||||
if (pci_vendor == NVIDIA_VEN && pci_subsystem_vendor == EVGA_SUB_VEN) {
|
||||
|
||||
strcpy(device_string, "/dev/");
|
||||
strcat(device_string, ent->d_name);
|
||||
test_fd = open(device_string, O_RDWR);
|
||||
|
||||
if (test_fd < 0)
|
||||
{
|
||||
printf("Failed to open device file %s, are you root or have permissions for i2c?\n", device_string);
|
||||
return -1;
|
||||
} else {
|
||||
} else {
|
||||
printf("Bad FW version read %s\n", device_string);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return num_gpus;
|
||||
}
|
||||
|
||||
/* Read a 16-bit unsigned int from a pci id file */
|
||||
unsigned short read_pci_id(char *device_path, char *field)
|
||||
{
|
||||
char *buf[16];
|
||||
char buf[16];
|
||||
char file_path[NAME_MAX];
|
||||
|
||||
strcpy(file_path, device_path);
|
||||
@@ -166,4 +102,23 @@ unsigned short read_pci_id(char *device_path, char *field)
|
||||
return (unsigned short)strtoul(buf, NULL, 16);
|
||||
}
|
||||
|
||||
|
||||
char *read_nvidia_pci_address(char *device_path)
|
||||
{
|
||||
char file_path[NAME_MAX];
|
||||
|
||||
char *ret = calloc(16 + 1, sizeof(char)); /* assuming pci ids could look as large as 00000000:0C:00.0 */
|
||||
|
||||
strcpy(file_path, device_path);
|
||||
strcat(file_path, "/name");
|
||||
|
||||
FILE *fp = fopen(file_path, "r");
|
||||
|
||||
if (fp == NULL)
|
||||
return NULL;
|
||||
|
||||
fscanf(fp, "NVIDIA i2c adapter %*u at %16s", ret);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user