mirror of
https://github.com/lm-sensors/lm-sensors.git
synced 2026-10-23 11:54:33 +00:00
libsensors: Consider all ancestor devices when determining bus type
Go through all ancestor devices of a hwmon device until we find a device that resides on a bus that we recognize. This change is meant to address hwmon devices that don't reside directly on a bus, but have another device in the middle of the hiearchy. For example: ACPI device -> thermal device -> hwmon device These kind of hwmon devices started appearing in the 4.19 kernel due to commit f6b6b52ef7a54160c0. It was not reported as a kernel regression and fixed in the kernel, because according to Documentation/admin-guide/sysfs-rules.rst, the change was OK to make (it says "Position of devices along device chain can change"). Fixes #133 Signed-off-by: Ondřej Lysoněk <olysonek@redhat.com>
This commit is contained in:
1 parent
567e6a3b36
commit
d4cb932567
1 file changed
+39
-17
+39
-17
@@ -707,28 +707,50 @@ static int find_bus_type(const char *dev_path,
|
||||
char linkpath[NAME_MAX];
|
||||
char subsys_path[NAME_MAX], *subsys;
|
||||
int sub_len;
|
||||
char *my_dev_path = NULL;
|
||||
int ret = 0;
|
||||
|
||||
my_dev_path = strdup(dev_path);
|
||||
if (my_dev_path == NULL)
|
||||
sensors_fatal_error(__func__, "Out of memory");
|
||||
|
||||
/* Find bus type */
|
||||
snprintf(linkpath, NAME_MAX, "%s/subsystem", dev_path);
|
||||
sub_len = readlink(linkpath, subsys_path, NAME_MAX - 1);
|
||||
if (sub_len < 0 && errno == ENOENT) {
|
||||
/* Fallback to "bus" link for kernels <= 2.6.17 */
|
||||
snprintf(linkpath, NAME_MAX, "%s/bus", dev_path);
|
||||
while (!ret && my_dev_path != NULL) {
|
||||
snprintf(linkpath, NAME_MAX, "%s/subsystem", my_dev_path);
|
||||
sub_len = readlink(linkpath, subsys_path, NAME_MAX - 1);
|
||||
}
|
||||
if (sub_len < 0) {
|
||||
/* Older kernels (<= 2.6.11) have neither the subsystem
|
||||
symlink nor the bus symlink */
|
||||
if (errno == ENOENT)
|
||||
subsys = NULL;
|
||||
else
|
||||
return -SENSORS_ERR_KERNEL;
|
||||
} else {
|
||||
subsys_path[sub_len] = '\0';
|
||||
subsys = strrchr(subsys_path, '/') + 1;
|
||||
if (sub_len < 0 && errno == ENOENT) {
|
||||
/* Fallback to "bus" link for kernels <= 2.6.17 */
|
||||
snprintf(linkpath, NAME_MAX, "%s/bus", my_dev_path);
|
||||
sub_len = readlink(linkpath, subsys_path, NAME_MAX - 1);
|
||||
}
|
||||
if (sub_len < 0) {
|
||||
/* Older kernels (<= 2.6.11) have neither the subsystem
|
||||
symlink nor the bus symlink */
|
||||
if (errno == ENOENT) {
|
||||
subsys = NULL;
|
||||
} else {
|
||||
ret = -SENSORS_ERR_KERNEL;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
subsys_path[sub_len] = '\0';
|
||||
subsys = strrchr(subsys_path, '/') + 1;
|
||||
}
|
||||
ret = classify_device(dev_name, subsys, entry);
|
||||
if (!ret) {
|
||||
snprintf(linkpath, NAME_MAX, "%s/device", my_dev_path);
|
||||
free(my_dev_path);
|
||||
my_dev_path = realpath(linkpath, NULL);
|
||||
if (my_dev_path != NULL)
|
||||
dev_name = strrchr(my_dev_path, '/') + 1;
|
||||
else if (errno == ENOMEM)
|
||||
sensors_fatal_error(__func__, "Out of memory");
|
||||
}
|
||||
}
|
||||
|
||||
return classify_device(dev_name, subsys, entry);
|
||||
if (my_dev_path != NULL)
|
||||
free(my_dev_path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* returns: number of devices added (0 or 1) if successful, <0 otherwise */
|
||||
|
||||
Reference in new issue
Block a user