/* This file is part of cputemp2maxfreq. Copyright (C) 2023-2024 pa4wdh cputemp2maxfreq is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License , or (at your option) any later version. cputemp2maxfreq is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with cputemp2maxfreq; see the file COPYING. If not, see . */ #include #include #include #include #include "cputemp2maxfreq.h" #include "debug.h" #include "sysfs.h" #include "cputemp.h" extern struct s_config config; // Check if the sensor matches our search criteria and validate the readout void cputemp_match_and_validate(char *name_file,char *input_file,char *sensor_name,struct s_sensor *sensor) { int datalen; long int testdata; char buf[255]; // Read the name to see if it matches what we're looking for datalen=sysfs_read_str(name_file,buf,sizeof(buf)); if (datalen<0) { DEBUG2_CPUTEMP("Failed to read name\n"); return; } DEBUG1_CPUTEMP("Name is: %s\n",buf); if (strncasecmp(buf,sensor_name,255)==0) { DEBUG2_CPUTEMP("Name machtes our search criteria\n"); DEBUG1_CPUTEMP("Input filename: %s\n",input_file); // Validate the sensor by reading it testdata=sysfs_read_long_int(input_file); DEBUG2_CPUTEMP("Input value: %ld\n",testdata); if ((testdata>=VALID_TEMP_MIN) && (testdata<=VALID_TEMP_MAX)) { DEBUG1_CPUTEMP("Input data is valid, marking sensor as valid\n"); sensor->valid=1; strncpy(sensor->name,buf,sizeof(buf)); strncpy(sensor->filename,input_file,sizeof(sensor->filename)); } else { DEBUG1_CPUTEMP("Input data is invalid, ignoring sensor\n"); } } } // Validate if we found a file named temp_label int cputemp_is_label(char *name) { int count; int offset; // Start with "temp" if (strncmp(name,"temp",4)!=0) return 0; // Must contain an underscore offset=0; for(count=5;count<7;count++) { if (name[count]=='_') { offset=count+1; break; } } if (offset==0) return 0; // Ends with "label" if (strncmp(name+offset,"label",5)!=0) return 0; if (name[offset+5]==0) return 1; return 0; } // Read a single hwmon directory and search for the requested sensor name void cputemp_read_hwmon(char *hwmon,char *sensor_name,struct s_sensor *sensor) { DIR *hwmon_dir; struct dirent *hwmon_dirent; char name_file[258]; char input_file[255]; int offset; DEBUG1_CPUTEMP("Searching for sensors in %s\n",hwmon); hwmon_dir=opendir(hwmon); if (hwmon_dir==NULL) { DEBUG1_CPUTEMP("Failed to open hwmon dir\n"); return; } hwmon_dirent=readdir(hwmon_dir); while((hwmon_dirent!=NULL) && (sensor->valid==0)) { DEBUG3_CPUTEMP("%s\n",hwmon_dirent->d_name); if (cputemp_is_label(hwmon_dirent->d_name)) { DEBUG2_CPUTEMP("Found label %s\n",hwmon_dirent->d_name); snprintf(name_file,258,"%s/%s",hwmon,hwmon_dirent->d_name); snprintf(input_file,258,"%s/%s",hwmon,hwmon_dirent->d_name); offset=(int) strlen(input_file)-5; strncpy(input_file+offset,"input",6); cputemp_match_and_validate(name_file,input_file,sensor_name,sensor); } hwmon_dirent=readdir(hwmon_dir); } closedir(hwmon_dir); // Some drivers do note have labels, so check the driver too if we didn't find anything so far if (sensor->valid==0) { DEBUG2_CPUTEMP("Checking driver name\n"); sprintf(name_file,"%s/name",hwmon); sprintf(input_file,"%s/temp1_input",hwmon); cputemp_match_and_validate(name_file,input_file,sensor_name,sensor); } } // Find all entries under /sys/class/hwmon and check them with // cputemp_read_hwmon void cputemp_find_sensor(char *sensor_name,struct s_sensor *sensor) { DIR *hwmon_dir; struct dirent *hwmon_dirent; char subdir[273]; DEBUG1_CPUTEMP("Searching for sensor %s\n",sensor_name); // Mark sensor data as invalid, it will be set valid if we find something sensor->valid=0; hwmon_dir=opendir("/sys/class/hwmon"); if (hwmon_dir==NULL) { DEBUG1_CPUTEMP("Failed to open /sys/class/hwmon, is sysfs mounted?\n"); return; } hwmon_dirent=readdir(hwmon_dir); while((hwmon_dirent!=NULL) && (sensor->valid==0)) { DEBUG3_CPUTEMP("Found file: %s\n",hwmon_dirent->d_name); // If the name starts with hwmon try to read it // Note that /sys/class/hwmon actually contains symlinks but we treat them like directories if (strncmp(hwmon_dirent->d_name,"hwmon",5)==0) { snprintf(subdir,273,"/sys/class/hwmon/%s",hwmon_dirent->d_name); DEBUG2_CPUTEMP("Found hwmon entry: %s\n",subdir); cputemp_read_hwmon(subdir,sensor_name,sensor); } hwmon_dirent=readdir(hwmon_dir); } closedir(hwmon_dir); }