Changeset 4359

Show
Ignore:
Timestamp:
04/09/07 16:09:21 (6 years ago)
Author:
jwrdegoede
Message:

dynamicly generate a sensors_chip_features_list entry for unknown chips based on their sysfs entries, by Bob Schlarmann and Luuk Kleiweg

Location:
lm-sensors/branches/lm-sensors-3.0.0/lib
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • lm-sensors/branches/lm-sensors-3.0.0/lib/chips.c

    r4357 r4359  
    2222#include "sensors.h" 
    2323#include "kernel/include/sensors.h" 
     24 
     25#define PLACEHOLDER_ELEMENTS {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0} 
    2426 
    2527/* For each chip, a list of features; 
     
    61626164 { SENSORS_CORETEMP_PREFIX, coretemp_features }, 
    61636165 { SENSORS_DME1737_PREFIX, dme1737_features }, 
     6166 PLACEHOLDER_ELEMENTS, 
    61646167 { 0 } 
    61656168}; 
  • lm-sensors/branches/lm-sensors-3.0.0/lib/data.h

    r4287 r4359  
    192192extern sensors_chip_features sensors_chip_features_list[]; 
    193193 
     194/* this should match the total number of elements in PLACEHOLDER_ELEMENTS */ 
     195#define N_PLACEHOLDER_ELEMENTS 10 
     196 
    194197#endif /* def LIB_SENSORS_DATA_H */ 
  • lm-sensors/branches/lm-sensors-3.0.0/lib/sysfs.c

    r4357 r4359  
    2525#include <errno.h> 
    2626#include <sysfs/libsysfs.h> 
     27#include <regex.h> 
    2728#include "data.h" 
    2829#include "error.h" 
     
    3536char sensors_sysfs_mount[NAME_MAX]; 
    3637 
     38#define DYNAMIC_CHIP_REGEX "\\([[:alpha:]]\\{1,\\}[[:digit:]]\\{0,\\}\\)\\(\\_[[:alpha:]]\\{1,\\}\\)\\{0,1\\}" 
     39 
     40static int sensors_read_dynamic_chip_check_mapping( 
     41        sensors_chip_feature *minor, 
     42        sensors_chip_feature *major, 
     43        regmatch_t *pmatch) 
     44{ 
     45        if (pmatch[1].rm_so == -1 || pmatch[2].rm_so == -1 ||  
     46                        strncmp(minor->data.name, major->data.name,  
     47                        pmatch[1].rm_eo - pmatch[1].rm_so)) { 
     48                return 0; 
     49        } else { 
     50                minor->data.mapping =  
     51                        minor->data.compute_mapping =  
     52                        major->data.number; 
     53                         
     54                return 1; 
     55        } 
     56} 
     57 
     58static  
     59sensors_chip_features sensors_read_dynamic_chip(struct sysfs_device *sysdir) 
     60{ 
     61        int fnum = 1, i, last_major = -1; 
     62        struct sysfs_attribute *attr; 
     63        struct dlist *attrs; 
     64        sensors_chip_features ret = {0, 0}; 
     65        sensors_chip_feature features[256], *dyn_features; 
     66        regex_t preg; 
     67        regmatch_t pmatch[3]; 
     68        char *name; 
     69                 
     70        attrs = sysfs_get_device_attributes(sysdir); 
     71         
     72        if (attrs == NULL) 
     73                return ret; 
     74         
     75        regcomp(&preg, DYNAMIC_CHIP_REGEX, 0); 
     76                 
     77        dlist_for_each_data(attrs, attr, struct sysfs_attribute) { 
     78                sensors_chip_feature feature = { { 0, }, 0, };   
     79                name = attr->name; 
     80                 
     81                if (!strcmp(name, "name")) { 
     82                        ret.prefix = strndup(attr->value, strlen(attr->value) - 1); 
     83                        continue; 
     84                } else if (regexec(&preg, name, 3, pmatch, 0) != 0) { 
     85                        continue; 
     86                } 
     87                 
     88                feature.data.number = fnum; 
     89                feature.data.mode = (attr->method & (SYSFS_METHOD_SHOW|SYSFS_METHOD_STORE)) ==  
     90                                                                                        (SYSFS_METHOD_SHOW|SYSFS_METHOD_STORE) ? 
     91                                                                                        SENSORS_MODE_RW : 
     92                                                        (attr->method & SYSFS_METHOD_SHOW) ? SENSORS_MODE_R : 
     93                                                        (attr->method & SYSFS_METHOD_STORE) ? SENSORS_MODE_W : 
     94                                                        SENSORS_MODE_NO_RW; 
     95                feature.data.mapping = SENSORS_NO_MAPPING; 
     96                feature.data.compute_mapping = SENSORS_NO_MAPPING; 
     97                         
     98                if (pmatch[2].rm_so != -1) { 
     99                        if (!strncmp(name + pmatch[2].rm_so, "_input", 
     100                                        pmatch[2].rm_eo - pmatch[2].rm_so)) { 
     101                                int last_match; 
     102                                 
     103                                /* copy only the part before the _ */ 
     104                                feature.data.name = strndup(name,  
     105                                        pmatch[1].rm_eo - pmatch[1].rm_so); 
     106                                 
     107                                /* check if the features previously read are sub devices of this major 
     108                                   and update their mapping accordingly */  
     109                                last_match = fnum - 1; 
     110                                for(i = fnum - 2; i >= 0; i--) { 
     111                                        if (regexec(&preg, features[i].data.name, 3, pmatch, 0) == -1 || 
     112                                                        !sensors_read_dynamic_chip_check_mapping(&features[i], 
     113                                                        &feature, pmatch)) { 
     114                                                break;                                           
     115                                        } else { 
     116                                                last_match = i; 
     117                                        } 
     118                                } 
     119                                 
     120                                /* if so the major should be in the list before any minor feature, 
     121                                        so swap with the oldest read */ 
     122                                if (last_match < fnum - 1) { 
     123                                        sensors_chip_feature tmp = features[last_match]; 
     124                                        features[last_match] = feature; 
     125                                        features[fnum - 1] = tmp; 
     126                                                         
     127                                        last_major = last_match; 
     128                                         
     129                                        goto NEXT_NUM; /* NOTE: goto used */ 
     130                                } else { 
     131                                        last_major = fnum - 1; 
     132                                } 
     133                                 
     134                        } else { 
     135                                feature.data.name = strdup(name); 
     136                         
     137                                if (last_major != -1 &&  
     138                                                !sensors_read_dynamic_chip_check_mapping(&feature, 
     139                                                                &features[last_major], pmatch)) { 
     140                                        last_major = -1; /* no more features for current major */ 
     141                                } 
     142                        } 
     143                } else { 
     144                        feature.data.name = strdup(name); 
     145                } 
     146                         
     147                features[fnum - 1] = feature;            
     148NEXT_NUM: 
     149                fnum++; 
     150        } 
     151                 
     152        regfree(&preg); 
     153         
     154        dyn_features = malloc(sizeof(sensors_chip_feature) * fnum); 
     155        if (dyn_features == NULL) { 
     156                sensors_fatal_error(__FUNCTION__,"Out of memory"); 
     157        } 
     158         
     159        for(i = 0; i < fnum - 1; i++) { 
     160                dyn_features[i] = features[i]; 
     161        } 
     162        dyn_features[fnum - 1].data.name = 0; 
     163         
     164        ret.feature = dyn_features; 
     165         
     166        return ret; 
     167} 
     168 
    37169/* returns !0 if sysfs filesystem was found, 0 otherwise */ 
    38170int sensors_init_sysfs(void) 
     
    47179static int sensors_read_one_sysfs_chip(struct sysfs_device *dev) 
    48180{ 
    49         int domain, bus, slot, fn; 
     181        static int total_dynamic = 0; 
     182        int domain, bus, slot, fn, i; 
    50183        struct sysfs_attribute *attr, *bus_attr; 
    51184        char bus_path[SYSFS_PATH_MAX]; 
     
    103236        } else 
    104237                return -SENSORS_ERR_PARSE; 
    105  
     238         
     239        /* check whether this chip is known in the static list */  
     240        for (i = 0; sensors_chip_features_list[i].prefix; i++) 
     241                if (!strcasecmp(sensors_chip_features_list[i].prefix, entry.name.prefix)) 
     242                        break; 
     243 
     244        /* if no chip definition matches */ 
     245        if (!sensors_chip_features_list[i].prefix &&  
     246                total_dynamic < N_PLACEHOLDER_ELEMENTS) { 
     247                sensors_chip_features n_entry = sensors_read_dynamic_chip(dev); 
     248 
     249                /* skip to end of list */ 
     250                for(i = 0; sensors_chip_features_list[i].prefix; i++); 
     251 
     252                sensors_chip_features_list[i] = n_entry;         
     253 
     254                total_dynamic++; 
     255        } 
     256                 
    106257        sensors_add_proc_chips(&entry); 
    107258