Changeset 5067
- Timestamp:
- 12/10/07 14:30:22 (10 months ago)
- Files:
-
- lm-sensors/branches/lm-sensors-3.0.0/CHANGES (modified) (1 diff)
- lm-sensors/branches/lm-sensors-3.0.0/INSTALL (modified) (1 diff)
- lm-sensors/branches/lm-sensors-3.0.0/lib/Module.mk (modified) (1 diff)
- lm-sensors/branches/lm-sensors-3.0.0/lib/sysfs.c (modified) (13 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
lm-sensors/branches/lm-sensors-3.0.0/CHANGES
r5063 r5067 4 4 SVN 5 5 documentation: Update the application writing guidelines 6 libsensors: No longer depend on libsysfs 6 7 Makefile: No warnings about ld configuration for staged installations 7 8 pwmconfig: Really hide errors on sysfs writes lm-sensors/branches/lm-sensors-3.0.0/INSTALL
r5037 r5067 15 15 * bison 16 16 * flex 17 * libsysfs header files (from sysfsutils-devel)18 17 * rrd header files (optional, for sensord) 19 18 20 19 Run-time dependencies: 21 * libsysfs (from sysfsutils)22 20 * perl (for sensors-detect) 23 21 * rrd (optional, for sensord) lm-sensors/branches/lm-sensors-3.0.0/lib/Module.mk
r5047 r5067 60 60 # How to create the shared library 61 61 $(MODULE_DIR)/$(LIBSHLIBNAME): $(LIBSHOBJECTS) 62 $(CC) -shared -Wl,-soname,$(LIBSHSONAME) -o $@ $^ -lc -lm -lsysfs62 $(CC) -shared -Wl,-soname,$(LIBSHSONAME) -o $@ $^ -lc -lm 63 63 64 64 $(MODULE_DIR)/$(LIBSHSONAME): $(MODULE_DIR)/$(LIBSHLIBNAME) lm-sensors/branches/lm-sensors-3.0.0/lib/sysfs.c
r4899 r5067 29 29 #include <limits.h> 30 30 #include <errno.h> 31 #include < sysfs/libsysfs.h>31 #include <dirent.h> 32 32 #include "data.h" 33 33 #include "error.h" … … 35 35 #include "general.h" 36 36 #include "sysfs.h" 37 38 39 /****************************************************************************/ 40 41 #define ATTR_MAX 128 42 43 /* 44 * Read an attribute from sysfs 45 * Returns a pointer to a freshly allocated string; free it yourself. 46 * If the file doesn't exist or can't be read, NULL is returned. 47 */ 48 static char *sysfs_read_attr(const char *device, const char *attr) 49 { 50 char path[NAME_MAX]; 51 char buf[ATTR_MAX], *p; 52 FILE *f; 53 54 snprintf(path, NAME_MAX, "%s/%s", device, attr); 55 56 if (!(f = fopen(path, "r"))) 57 return NULL; 58 p = fgets(buf, ATTR_MAX, f); 59 fclose(f); 60 if (!p) 61 return NULL; 62 63 /* Last byte is a '\n'; chop that off */ 64 p = strndup(buf, strlen(buf) - 1); 65 if (!p) 66 sensors_fatal_error(__FUNCTION__, "out of memory"); 67 return p; 68 } 69 70 /* 71 * Call an arbitrary function for each class device of the given class 72 * Returns 0 on success (all calls returned 0), a positive errno for 73 * local errors, or a negative error value if any call fails. 74 */ 75 static int sysfs_foreach_classdev(const char *class_name, 76 int (*func)(char *, const char*)) 77 { 78 char path[NAME_MAX]; 79 int path_off, ret; 80 DIR *dir; 81 struct dirent *ent; 82 83 path_off = snprintf(path, NAME_MAX, "%s/class/%s", 84 sensors_sysfs_mount, class_name); 85 if (!(dir = opendir(path))) 86 return errno; 87 88 ret = 0; 89 while (!ret && (ent = readdir(dir))) { 90 if (ent->d_name[0] == '.') /* skip hidden entries */ 91 continue; 92 93 snprintf(path + path_off, NAME_MAX - path_off, "/%s", 94 ent->d_name); 95 ret = func(path, ent->d_name); 96 } 97 98 closedir(dir); 99 return ret; 100 } 101 102 /* 103 * Call an arbitrary function for each device of the given bus type 104 * Returns 0 on success (all calls returned 0), a positive errno for 105 * local errors, or a negative error value if any call fails. 106 */ 107 static int sysfs_foreach_busdev(const char *bus_type, 108 int (*func)(char *, const char*)) 109 { 110 char path[NAME_MAX]; 111 int path_off, ret; 112 DIR *dir; 113 struct dirent *ent; 114 115 path_off = snprintf(path, NAME_MAX, "%s/bus/%s/devices", 116 sensors_sysfs_mount, bus_type); 117 if (!(dir = opendir(path))) 118 return errno; 119 120 ret = 0; 121 while (!ret && (ent = readdir(dir))) { 122 if (ent->d_name[0] == '.') /* skip hidden entries */ 123 continue; 124 125 snprintf(path + path_off, NAME_MAX - path_off, "/%s", 126 ent->d_name); 127 ret = func(path, ent->d_name); 128 } 129 130 closedir(dir); 131 return ret; 132 } 133 134 /****************************************************************************/ 37 135 38 136 char sensors_sysfs_mount[NAME_MAX]; … … 177 275 } 178 276 277 static int sensors_get_attr_mode(const char *device, const char *attr) 278 { 279 char path[NAME_MAX]; 280 struct stat st; 281 int mode = 0; 282 283 snprintf(path, NAME_MAX, "%s/%s", device, attr); 284 if (!stat(path, &st)) { 285 if (st.st_mode & S_IRUSR) 286 mode |= SENSORS_MODE_R; 287 if (st.st_mode & S_IWUSR) 288 mode |= SENSORS_MODE_W; 289 } 290 return mode; 291 } 292 179 293 static int sensors_read_dynamic_chip(sensors_chip_features *chip, 180 struct sysfs_device *sysdir)294 const char *dev_path) 181 295 { 182 296 int i, fnum = 0, sfnum = 0, prev_slot; 183 struct sysfs_attribute *attr;184 struct d list *attrs;297 DIR *dir; 298 struct dirent *ent; 185 299 sensors_subfeature *all_subfeatures; 186 300 sensors_subfeature *dyn_subfeatures; … … 189 303 sensors_subfeature_type sftype; 190 304 191 attrs = sysfs_get_device_attributes(sysdir); 192 193 if (attrs == NULL) 194 return -ENOENT; 305 if (!(dir = opendir(dev_path))) 306 return -errno; 195 307 196 308 /* We use a large sparse table at first to store all found … … 202 314 sensors_fatal_error(__FUNCTION__, "Out of memory"); 203 315 204 dlist_for_each_data(attrs, attr, struct sysfs_attribute) {205 char *name = attr->name;316 while ((ent = readdir(dir))) { 317 char *name = ent->d_name; 206 318 int nr; 319 320 if (ent->d_name[0] == '.') 321 continue; 207 322 208 323 sftype = sensors_subfeature_get_type(name, &nr); … … 258 373 if (!(sftype & 0x80)) 259 374 all_subfeatures[i].flags |= SENSORS_COMPUTE_MAPPING; 260 if (attr->method & SYSFS_METHOD_SHOW) 261 all_subfeatures[i].flags |= SENSORS_MODE_R; 262 if (attr->method & SYSFS_METHOD_STORE) 263 all_subfeatures[i].flags |= SENSORS_MODE_W; 375 all_subfeatures[i].flags |= sensors_get_attr_mode(dev_path, name); 264 376 265 377 sfnum++; 266 378 } 379 closedir(dir); 267 380 268 381 if (!sfnum) { /* No subfeature */ … … 334 447 struct stat statbuf; 335 448 336 /* libsysfs will return success even if sysfs is not mounted, 337 so we have to double-check */ 338 if (sysfs_get_mnt_path(sensors_sysfs_mount, NAME_MAX) 339 || stat(sensors_sysfs_mount, &statbuf) < 0 449 snprintf(sensors_sysfs_mount, NAME_MAX, "%s", "/sys"); 450 if (stat(sensors_sysfs_mount, &statbuf) < 0 340 451 || statbuf.st_nlink <= 2) /* Empty directory */ 341 452 return 0; … … 345 456 346 457 /* returns: 0 if successful, !0 otherwise */ 347 static int sensors_read_one_sysfs_chip( struct sysfs_device *dev)458 static int sensors_read_one_sysfs_chip(char *dev_path, const char *dev_name) 348 459 { 349 460 int domain, bus, slot, fn; 350 461 int err = -SENSORS_ERR_KERNEL; 351 struct sysfs_attribute *attr,*bus_attr;352 char bus_path[ SYSFS_PATH_MAX];462 char *bus_attr; 463 char bus_path[NAME_MAX]; 353 464 sensors_chip_features entry; 354 465 355 466 /* ignore any device without name attribute */ 356 if (!( attr = sysfs_get_device_attr(dev, "name")))467 if (!(entry.chip.prefix = sysfs_read_attr(dev_path, "name"))) 357 468 return 0; 358 469 359 /* NB: attr->value[attr->len-1] == '\n'; chop that off */ 360 entry.chip.prefix = strndup(attr->value, attr->len - 1); 361 if (!entry.chip.prefix) 362 sensors_fatal_error(__FUNCTION__, "out of memory"); 363 364 entry.chip.path = strdup(dev->path); 470 entry.chip.path = strdup(dev_path); 365 471 if (!entry.chip.path) 366 472 sensors_fatal_error(__FUNCTION__, "out of memory"); 367 473 368 if (sscanf(dev ->name, "%hd-%x", &entry.chip.bus.nr, &entry.chip.addr) == 2) {474 if (sscanf(dev_name, "%hd-%x", &entry.chip.bus.nr, &entry.chip.addr) == 2) { 369 475 /* find out if legacy ISA or not */ 370 476 if (entry.chip.bus.nr == 9191) { … … 374 480 entry.chip.bus.type = SENSORS_BUS_TYPE_I2C; 375 481 snprintf(bus_path, sizeof(bus_path), 376 "%s/class/i2c-adapter/i2c-%d/device /name",482 "%s/class/i2c-adapter/i2c-%d/device", 377 483 sensors_sysfs_mount, entry.chip.bus.nr); 378 484 379 if ((bus_attr = sysfs_open_attribute(bus_path))) { 380 if (sysfs_read_attribute(bus_attr)) { 381 sysfs_close_attribute(bus_attr); 382 goto exit_free; 383 } 384 385 if (bus_attr->value 386 && !strncmp(bus_attr->value, "ISA ", 4)) { 485 if ((bus_attr = sysfs_read_attr(bus_path, "name"))) { 486 if (!strncmp(bus_attr, "ISA ", 4)) { 387 487 entry.chip.bus.type = SENSORS_BUS_TYPE_ISA; 388 488 entry.chip.bus.nr = 0; 389 489 } 390 490 391 sysfs_close_attribute(bus_attr);491 free(bus_attr); 392 492 } 393 493 } 394 } else if (sscanf(dev ->name, "spi%hd.%d", &entry.chip.bus.nr,494 } else if (sscanf(dev_name, "spi%hd.%d", &entry.chip.bus.nr, 395 495 &entry.chip.addr) == 2) { 396 496 /* SPI */ 397 497 entry.chip.bus.type = SENSORS_BUS_TYPE_SPI; 398 } else if (sscanf(dev ->name, "%*[a-z0-9_].%d", &entry.chip.addr) == 1) {498 } else if (sscanf(dev_name, "%*[a-z0-9_].%d", &entry.chip.addr) == 1) { 399 499 /* must be new ISA (platform driver) */ 400 500 entry.chip.bus.type = SENSORS_BUS_TYPE_ISA; 401 501 entry.chip.bus.nr = 0; 402 } else if (sscanf(dev ->name, "%x:%x:%x.%x", &domain, &bus, &slot, &fn) == 4) {502 } else if (sscanf(dev_name, "%x:%x:%x.%x", &domain, &bus, &slot, &fn) == 4) { 403 503 /* PCI */ 404 504 entry.chip.addr = (domain << 16) + (bus << 8) + (slot << 3) + fn; … … 412 512 } 413 513 414 if (sensors_read_dynamic_chip(&entry, dev ) < 0)514 if (sensors_read_dynamic_chip(&entry, dev_path) < 0) 415 515 goto exit_free; 416 516 if (!entry.subfeature) { /* No subfeature, discard chip */ … … 431 531 static int sensors_read_sysfs_chips_compat(void) 432 532 { 433 struct sysfs_bus *bus; 434 struct dlist *devs; 435 struct sysfs_device *dev; 436 int ret = 0; 437 438 if (!(bus = sysfs_open_bus("i2c"))) { 439 if (errno && errno != ENOENT) 440 ret = -SENSORS_ERR_KERNEL; 441 goto exit0; 442 } 443 444 if (!(devs = sysfs_get_bus_devices(bus))) { 445 if (errno && errno != ENOENT) 446 ret = -SENSORS_ERR_KERNEL; 447 goto exit1; 448 } 449 450 dlist_for_each_data(devs, dev, struct sysfs_device) 451 if ((ret = sensors_read_one_sysfs_chip(dev))) 452 goto exit1; 453 454 exit1: 455 /* this frees bus and devs */ 456 sysfs_close_bus(bus); 457 458 exit0: 459 return ret; 533 int ret; 534 535 ret = sysfs_foreach_busdev("i2c", sensors_read_one_sysfs_chip); 536 if (ret && ret != ENOENT) 537 return -SENSORS_ERR_KERNEL; 538 539 return 0; 540 } 541 542 static int sensors_add_hwmon_device(char *path, const char *classdev) 543 { 544 char device[NAME_MAX]; 545 int path_off = strlen(path); 546 int dev_len; 547 (void)classdev; /* hide warning */ 548 549 snprintf(path + path_off, NAME_MAX - path_off, "/device"); 550 dev_len = readlink(path, device, NAME_MAX - 1); 551 if (dev_len < 0) 552 return -SENSORS_ERR_KERNEL; 553 device[dev_len] = '\0'; 554 555 return sensors_read_one_sysfs_chip(path, strrchr(device, '/') + 1); 460 556 } 461 557 … … 463 559 int sensors_read_sysfs_chips(void) 464 560 { 465 struct sysfs_class *cls; 466 struct dlist *clsdevs; 467 struct sysfs_class_device *clsdev; 468 int ret = 0; 469 470 if (!(cls = sysfs_open_class("hwmon"))) { 561 int ret; 562 563 ret = sysfs_foreach_classdev("hwmon", sensors_add_hwmon_device); 564 if (ret == ENOENT) { 471 565 /* compatibility function for kernel 2.6.n where n <= 13 */ 472 566 return sensors_read_sysfs_chips_compat(); 473 567 } 474 568 475 if (!(clsdevs = sysfs_get_class_devices(cls))) { 476 if (errno && errno != ENOENT) 477 ret = -SENSORS_ERR_KERNEL; 478 goto exit; 479 } 480 481 dlist_for_each_data(clsdevs, clsdev, struct sysfs_class_device) { 482 struct sysfs_device *dev; 483 if (!(dev = sysfs_get_classdev_device(clsdev))) { 484 ret = -SENSORS_ERR_KERNEL; 485 goto exit; 486 } 487 if ((ret = sensors_read_one_sysfs_chip(dev))) 488 goto exit; 489 } 490 491 exit: 492 /* this frees cls and clsdevs */ 493 sysfs_close_class(cls); 569 if (ret > 0) 570 ret = -SENSORS_ERR_KERNEL; 494 571 return ret; 572 } 573 574 /* returns 0 if successful, !0 otherwise */ 575 static int sensors_add_i2c_bus(char *path, const char *classdev) 576 { 577 sensors_bus entry; 578 579 if (sscanf(classdev, "i2c-%hd", &entry.bus.nr) != 1 || 580 entry.bus.nr == 9191) /* legacy ISA */ 581 return 0; 582 entry.bus.type = SENSORS_BUS_TYPE_I2C; 583 584 /* Get the adapter name from the classdev "name" attribute 585 * (Linux 2.6.20 and later). If it fails, fall back to 586 * the device "name" attribute (for older kernels). */ 587 entry.adapter = sysfs_read_attr(path, "name"); 588 if (!entry.adapter) 589 entry.adapter = sysfs_read_attr(path, "device/name"); 590 if (entry.adapter) 591 sensors_add_proc_bus(&entry); 592 593 return 0; 495 594 } 496 595 … … 498 597 int sensors_read_sysfs_bus(void) 499 598 { 500 struct sysfs_class *cls; 501 struct dlist *clsdevs; 502 struct sysfs_class_device *clsdev; 503 sensors_bus entry; 504 int ret = 0; 505 506 if (!(cls = sysfs_open_class("i2c-adapter"))) { 507 if (errno && errno != ENOENT) 508 ret = -SENSORS_ERR_KERNEL; 509 goto exit0; 510 } 511 512 if (!(clsdevs = sysfs_get_class_devices(cls))) { 513 if (errno && errno != ENOENT) 514 ret = -SENSORS_ERR_KERNEL; 515 goto exit1; 516 } 517 518 dlist_for_each_data(clsdevs, clsdev, struct sysfs_class_device) { 519 struct sysfs_device *dev; 520 struct sysfs_attribute *attr; 521 522 /* Get the adapter name from the classdev "name" attribute 523 * (Linux 2.6.20 and later). If it fails, fall back to 524 * the device "name" attribute (for older kernels). */ 525 if (!(attr = sysfs_get_classdev_attr(clsdev, "name")) 526 && !((dev = sysfs_get_classdev_device(clsdev)) && 527 (attr = sysfs_get_device_attr(dev, "name")))) 528 continue; 529 530 if (sscanf(clsdev->name, "i2c-%hd", &entry.bus.nr) != 1 || 531 entry.bus.nr == 9191) /* legacy ISA */ 532 continue; 533 entry.bus.type = SENSORS_BUS_TYPE_I2C; 534 535 /* NB: attr->value[attr->len-1] == '\n'; chop that off */ 536 entry.adapter = strndup(attr->value, attr->len - 1); 537 if (!entry.adapter) 538 sensors_fatal_error(__FUNCTION__, "out of memory"); 539 540 sensors_add_proc_bus(&entry); 541 } 542 543 exit1: 544 /* this frees *cls _and_ *clsdevs */ 545 sysfs_close_class(cls); 546 547 exit0: 548 return ret; 599 int ret; 600 601 ret = sysfs_foreach_classdev("i2c-adapter", sensors_add_i2c_bus); 602 if (ret && ret != ENOENT) 603 return -SENSORS_ERR_KERNEL; 604 605 return 0; 549 606 } 550 607
