Changeset 3095

Show
Ignore:
Timestamp:
09/18/05 22:38:19 (8 years ago)
Author:
mmh
Message:

(mmh)
This patch replaces the I2C chip enumeration (through sysfs) in lib/proc.c
with new functions in lib/sysfs (using libsysfs). The patch also updates
the init code accordingly.

Location:
lm-sensors/trunk/lib
Files:
4 modified

Legend:

Unmodified
Added
Removed
  • lm-sensors/trunk/lib/init.c

    r3094 r3095  
    4242  int res; 
    4343  sensors_cleanup(); 
    44   if ((res = sensors_read_proc_chips())) 
    45     return res; 
    4644  if (sensors_init_sysfs()) { 
    47     if ((res = sensors_read_sysfs_bus())) 
     45    if ((res = sensors_read_sysfs_chips()) || (res = sensors_read_sysfs_bus())) 
    4846      return res; 
    4947  } else { 
    50     if ((res = sensors_read_proc_bus())) 
     48    if ((res = sensors_read_proc_chips()) || (res = sensors_read_proc_bus())) 
    5149      return res; 
    5250  } 
  • lm-sensors/trunk/lib/proc.c

    r3094 r3095  
    4747        int *sysmag, char *altsysname); 
    4848 
    49 /* return value: <0 on error, 0 if chip is ignored, 1 if chip is added 
    50    Warning: name is overwritten */ 
    51 static int sensors_read_one_sysfs_chip(char *name, char *dirname, char *id) 
    52 { 
    53         FILE *f; 
    54         char x[51]; 
    55         int len; 
    56         sensors_proc_chips_entry entry; 
    57  
    58         if ((f = fopen(name, "r")) == NULL) 
    59                 return -SENSORS_ERR_PROC; 
    60                  
    61         if (fscanf(f, "%50[a-zA-z0-9_ ]%n", x, &len) != 1) { 
    62                 fclose(f); 
    63                 return -SENSORS_ERR_CHIP_NAME; 
    64         } 
    65         fclose(f); 
    66  
    67         /* We don't care about subclients */ 
    68         if (len >= 10 && !strcmp(x + len - 10, " subclient")) 
    69                 return 0; 
    70  
    71         /* also, ignore eeproms for all 2.6.x kernels */ 
    72         if (!strcmp(x, "eeprom")) 
    73                 return 0; 
    74  
    75         /* Fill in the entry fields */ 
    76         entry.name.prefix = strdup(x); 
    77         if (entry.name.prefix == NULL) 
    78                 return -SENSORS_ERR_PARSE; /* No better error :( */ 
    79         entry.name.busname = strdup(dirname); 
    80         if (entry.name.prefix == NULL) 
    81                 return -SENSORS_ERR_PARSE; /* No better error :( */ 
    82         sscanf(id, "%d-%x", &entry.name.bus, &entry.name.addr); 
    83  
    84         /* Find out if ISA or not */ 
    85         sprintf(name, "%s/class/i2c-adapter/i2c-%d/device/name", 
    86                 sensors_sysfs_mount, entry.name.bus); 
    87         if ((f = fopen(name, "r")) != NULL) { 
    88                 if (fgets(x, 5, f) != NULL 
    89                  && !strncmp(x, "ISA ", 4)) 
    90                         entry.name.bus = SENSORS_CHIP_NAME_BUS_ISA; 
    91                 fclose(f); 
    92         } 
    93  
    94         sensors_add_proc_chips(&entry); 
    95          
    96         return 1; 
    97 } 
    98  
    9949/* This reads /proc/sys/dev/sensors/chips into memory */ 
    10050int sensors_read_proc_chips(void) 
    10151{ 
    102         struct dirent *de; 
    103         DIR *dir; 
    104         char sysfs[NAME_MAX], n[NAME_MAX]; 
    105         char dirname[NAME_MAX]; 
    106         int res; 
    107  
    108         int name[3] = { CTL_DEV, DEV_SENSORS, SENSORS_CHIPS }; 
    109         int buflen = BUF_LEN; 
    110         char *bufptr = buf; 
    111         sensors_proc_chips_entry entry; 
    112         int lineno; 
    113  
    114         if (!sensors_found_sysfs) 
    115                 goto proc; 
    116  
    117         /* Try /sys/class/hwmon first (Linux 2.6.14 and up) */ 
    118         strncpy(sysfs, sensors_sysfs_mount, sizeof(sysfs) - 1); 
    119         sysfs[sizeof(sysfs) - 1] = '\0'; 
    120         strncat(sysfs, "/class/hwmon", sizeof(sysfs) - strlen(sysfs) - 1); 
    121  
    122         dir = opendir(sysfs); 
    123         if (! dir) 
    124                 goto oldsys; 
    125  
    126         while ((de = readdir(dir)) != NULL) { 
    127                 char lnk[NAME_MAX]; 
    128                 char *id; 
    129  
    130                 if (de->d_name[0] == '.') 
    131                         continue; 
    132  
    133                 sprintf(n, "%s/%s", sysfs, de->d_name); 
    134                 strcpy(dirname, n); 
    135                 strcat(n, "/device"); 
    136                 if ((res = readlink(n, lnk, NAME_MAX)) < 0) 
    137                         continue; 
    138                 lnk[res] = '\0'; 
    139  
    140                 if (lnk[0] == '/') /* absolute link (unlikely) */ 
    141                         strcpy(n, lnk); 
    142                 else if (strncmp(lnk, "../", 3)) /* simple relative link */ 
    143                         sprintf(n, "%s/%s/%s", sysfs, de->d_name, lnk); 
    144                 else { /* relative link with ../s, can be simplified */ 
    145                         char *p_lnk = lnk + 3; 
    146                         int l = strlen(sysfs) - 1; 
    147                         while (!strncmp(p_lnk, "../", 3)) { 
    148                                 p_lnk += 3; 
    149                                 while (l && sysfs[--l] != '/') ; 
    150                         } 
    151                         strncpy(n, sysfs, ++l); 
    152                         strcpy(n + l, p_lnk);  
    153                 } 
    154                 strcpy(dirname, n); 
    155                 id = rindex(n, '/'); 
    156                 id++; 
    157                 strcat(n, "/name"); 
    158  
    159                 sensors_read_one_sysfs_chip(n, dirname, id); 
    160         } 
    161         closedir(dir); 
    162         return 0; 
    163  
    164 oldsys: 
    165         /* Fall back to /sys/bus/i2c (Linux 2.5 to 2.6.13) */ 
    166         strncpy(sysfs, sensors_sysfs_mount, sizeof(sysfs) - 1); 
    167         sysfs[sizeof(sysfs) - 1] = '\0'; 
    168         strncat(sysfs, "/bus/i2c/devices", sizeof(sysfs) - strlen(sysfs) - 1); 
    169  
    170         dir = opendir(sysfs); 
    171         if (! dir) 
    172                 goto proc; 
    173  
    174         while ((de = readdir(dir)) != NULL) { 
    175                 if (!strcmp(de->d_name, ".")) 
    176                         continue; 
    177                 if (!strcmp(de->d_name, "..")) 
    178                         continue; 
    179 /* 
    180                 if (de->d_type != DT_DIR && de->d_type != DT_LNK) 
    181                         continue; 
    182 */ 
    183  
    184                 sprintf(n, "%s/%s", sysfs, de->d_name); 
    185                 strcpy(dirname, n); 
    186                 strcat(n, "/name"); 
    187  
    188                 sensors_read_one_sysfs_chip(n, dirname, de->d_name); 
    189         } 
    190         closedir(dir); 
    191         return 0; 
    192  
    193 proc: 
     52  int res; 
     53 
     54  int name[3] = { CTL_DEV, DEV_SENSORS, SENSORS_CHIPS }; 
     55  int buflen = BUF_LEN; 
     56  char *bufptr = buf; 
     57  sensors_proc_chips_entry entry; 
     58  int lineno; 
    19459 
    19560  if (sysctl(name, 3, bufptr, &buflen, NULL, 0)) 
  • lm-sensors/trunk/lib/sysfs.c

    r3094 r3095  
    1717    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
    1818*/ 
     19 
     20/* this define needed for strndup() */ 
     21#define _GNU_SOURCE 
    1922 
    2023#include <string.h> 
     
    4043} 
    4144 
     45/* returns: 0 if successful, !0 otherwise */ 
     46static int sensors_read_one_sysfs_chip(struct sysfs_device *dev) 
     47{ 
     48        struct sysfs_attribute *attr, *bus_attr; 
     49        char bus_path[SYSFS_PATH_MAX]; 
     50        sensors_proc_chips_entry entry; 
     51 
     52        /* ignore any device without name attribute */ 
     53        if (!(attr = sysfs_get_device_attr(dev, "name"))) 
     54                return 0; 
     55 
     56        /* ignore subclients */ 
     57        if (attr->len >= 11 && !strcmp(attr->value + attr->len - 11, 
     58                        " subclient\n")) 
     59                return 0; 
     60 
     61        /* also ignore eeproms */ 
     62        if (!strcmp(attr->value, "eeprom\n")) 
     63                return 0; 
     64 
     65        /* NB: attr->value[attr->len-1] == '\n'; chop that off */ 
     66        entry.name.prefix = strndup(attr->value, attr->len - 1); 
     67        if (!entry.name.prefix) 
     68                sensors_fatal_error(__FUNCTION__, "out of memory"); 
     69 
     70        entry.name.busname = strdup(dev->path); 
     71        if (!entry.name.busname) 
     72                sensors_fatal_error(__FUNCTION__, "out of memory"); 
     73 
     74        if (sscanf(dev->name, "%d-%x", &entry.name.bus, &entry.name.addr) != 2) 
     75                return -SENSORS_ERR_PARSE; 
     76 
     77        /* find out if ISA or not */ 
     78        snprintf(bus_path, sizeof(bus_path), 
     79                        "%s/class/i2c-adapter/i2c-%d/device/name", 
     80                        sensors_sysfs_mount, entry.name.bus); 
     81 
     82        if ((bus_attr = sysfs_open_attribute(bus_path))) { 
     83                if (sysfs_read_attribute(bus_attr)) 
     84                        return -SENSORS_ERR_PARSE; 
     85 
     86                if (bus_attr->value && !strncmp(bus_attr->value, "ISA ", 4)) 
     87                        entry.name.bus = SENSORS_CHIP_NAME_BUS_ISA; 
     88 
     89                sysfs_close_attribute(bus_attr); 
     90        } 
     91 
     92        sensors_add_proc_chips(&entry); 
     93 
     94        return 0; 
     95} 
     96 
     97/* returns 0 if successful, !0 otherwise */ 
     98static int sensors_read_sysfs_chips_compat(void) 
     99{ 
     100        struct sysfs_bus *bus; 
     101        struct dlist *devs; 
     102        struct sysfs_device *dev; 
     103        int ret = 0; 
     104 
     105        if (!(bus = sysfs_open_bus("i2c"))) { 
     106                ret = -SENSORS_ERR_PROC; 
     107                goto exit0; 
     108        } 
     109 
     110        if (!(devs = sysfs_get_bus_devices(bus))) { 
     111                ret = -SENSORS_ERR_PROC; 
     112                goto exit1; 
     113        } 
     114 
     115        dlist_for_each_data(devs, dev, struct sysfs_device) 
     116                if ((ret = sensors_read_one_sysfs_chip(dev))) 
     117                        goto exit1; 
     118 
     119exit1: 
     120        /* this frees bus and devs */ 
     121        sysfs_close_bus(bus); 
     122 
     123exit0: 
     124        return ret; 
     125} 
     126 
     127/* returns 0 if successful, !0 otherwise */ 
     128int sensors_read_sysfs_chips(void) 
     129{ 
     130        struct sysfs_class *cls; 
     131        struct dlist *clsdevs; 
     132        struct sysfs_class_device *clsdev; 
     133        int ret = 0; 
     134 
     135        if (!(cls = sysfs_open_class("hwmon"))) { 
     136                /* compatibility function for kernel 2.6.n where n <= 13 */ 
     137                return sensors_read_sysfs_chips_compat(); 
     138        } 
     139 
     140        if (!(clsdevs = sysfs_get_class_devices(cls))) { 
     141                ret = -SENSORS_ERR_PROC; 
     142                goto exit; 
     143        } 
     144 
     145        dlist_for_each_data(clsdevs, clsdev, struct sysfs_class_device) { 
     146                struct sysfs_device *dev; 
     147                if (!(dev = sysfs_get_classdev_device(clsdev))) { 
     148                        ret = -SENSORS_ERR_PROC; 
     149                        goto exit; 
     150                } 
     151                if ((ret = sensors_read_one_sysfs_chip(dev))) 
     152                        goto exit; 
     153        } 
     154 
     155exit: 
     156        /* this frees cls and clsdevs */ 
     157        sysfs_close_class(cls); 
     158        return ret; 
     159} 
     160 
    42161/* returns 0 if successful, !0 otherwise */ 
    43162int sensors_read_sysfs_bus(void) 
  • lm-sensors/trunk/lib/sysfs.h

    r3094 r3095  
    2727extern int sensors_init_sysfs(void); 
    2828 
     29extern int sensors_read_sysfs_chips(void); 
     30 
    2931extern int sensors_read_sysfs_bus(void); 
    3032