summaryrefslogtreecommitdiff
path: root/lib/sysfs.c
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2008-01-05 12:31:55 +0000
committerJean Delvare <khali@linux-fr.org>2008-01-05 12:31:55 +0000
commit5af7917c1fbd3eabb2f2b7d6acd7579fa5d4ad67 (patch)
treeab2ffa387865d879050d7d795cfe5ad8d1d28f54 /lib/sysfs.c
parent7a2649483ecaa10641c4918dffb956cb01f70b4c (diff)
downloadlm-sensors-git-5af7917c1fbd3eabb2f2b7d6acd7579fa5d4ad67.tar.gz
Get the device type from the subsystem symlink, rather than
guessing it from how the device identifier looks like. For kernels <= 2.6.17, we use the bus symlink instead. For kernels <= 2.6.11, neither symlink exist so we fallback to the old type guessing approach. It doesn't really matter as all hwmon devices were i2c devices back then. git-svn-id: http://lm-sensors.org/svn/lm-sensors/branches/lm-sensors-3.0.0@5092 7894878c-1315-0410-8ee3-d5d059ff63e0
Diffstat (limited to 'lib/sysfs.c')
-rw-r--r--lib/sysfs.c49
1 files changed, 40 insertions, 9 deletions
diff --git a/lib/sysfs.c b/lib/sysfs.c
index aa421c04..9a87ba26 100644
--- a/lib/sysfs.c
+++ b/lib/sysfs.c
@@ -461,6 +461,9 @@ static int sensors_read_one_sysfs_chip(const char *dev_path, const char *dev_nam
int err = -SENSORS_ERR_KERNEL;
char *bus_attr;
char bus_path[NAME_MAX];
+ char linkpath[NAME_MAX];
+ char subsys_path[NAME_MAX], *subsys;
+ int sub_len;
sensors_chip_features entry;
/* ignore any device without name attribute */
@@ -471,7 +474,29 @@ static int sensors_read_one_sysfs_chip(const char *dev_path, const char *dev_nam
if (!entry.chip.path)
sensors_fatal_error(__FUNCTION__, "out of memory");
- if (sscanf(dev_name, "%hd-%x", &entry.chip.bus.nr, &entry.chip.addr) == 2) {
+ /* 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);
+ 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
+ goto exit_free;
+ } else {
+ subsys_path[sub_len] = '\0';
+ subsys = strrchr(subsys_path, '/') + 1;
+ }
+
+ if ((!subsys || !strcmp(subsys, "i2c")) &&
+ sscanf(dev_name, "%hd-%x", &entry.chip.bus.nr,
+ &entry.chip.addr) == 2) {
/* find out if legacy ISA or not */
if (entry.chip.bus.nr == 9191) {
entry.chip.bus.type = SENSORS_BUS_TYPE_ISA;
@@ -491,24 +516,30 @@ static int sensors_read_one_sysfs_chip(const char *dev_path, const char *dev_nam
free(bus_attr);
}
}
- } else if (sscanf(dev_name, "spi%hd.%d", &entry.chip.bus.nr,
- &entry.chip.addr) == 2) {
+ } else
+ if ((!subsys || !strcmp(subsys, "spi")) &&
+ sscanf(dev_name, "spi%hd.%d", &entry.chip.bus.nr,
+ &entry.chip.addr) == 2) {
/* SPI */
entry.chip.bus.type = SENSORS_BUS_TYPE_SPI;
- } else if (sscanf(dev_name, "%*[a-z0-9_].%d", &entry.chip.addr) == 1) {
+ } else
+ if ((!subsys || !strcmp(subsys, "platform"))) {
/* must be new ISA (platform driver) */
+ if (sscanf(dev_name, "%*[a-z0-9_].%d", &entry.chip.addr) != 1)
+ entry.chip.addr = 0;
entry.chip.bus.type = SENSORS_BUS_TYPE_ISA;
entry.chip.bus.nr = 0;
- } else if (sscanf(dev_name, "%x:%x:%x.%x", &domain, &bus, &slot, &fn) == 4) {
+ } else
+ if ((!subsys || !strcmp(subsys, "pci")) &&
+ sscanf(dev_name, "%x:%x:%x.%x", &domain, &bus, &slot, &fn) == 4) {
/* PCI */
entry.chip.addr = (domain << 16) + (bus << 8) + (slot << 3) + fn;
entry.chip.bus.type = SENSORS_BUS_TYPE_PCI;
entry.chip.bus.nr = 0;
} else {
- /* platform device with no id? */
- entry.chip.bus.type = SENSORS_BUS_TYPE_ISA;
- entry.chip.bus.nr = 0;
- entry.chip.addr = 0;
+ /* Ignore unknown device */
+ err = 0;
+ goto exit_free;
}
if (sensors_read_dynamic_chip(&entry, dev_path) < 0)