root/lm-sensors/branches/lm-sensors-3.0.0/lib/data.c @ 5163

Revision 5163, 6.7 KB (checked in by khali, 6 years ago)

Patch from Aurelien Jarno:

I have just noticed that the FSF address is the old one in all files
except COPYING. Please find a patch below to fix that.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2    data.c - Part of libsensors, a Linux library for reading sensor data.
3    Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl>
4    Copyright (C) 2007        Jean Delvare <khali@linux-fr.org>
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19    MA 02110-1301 USA.
20*/
21
22/* this define needed for strndup() */
23#define _GNU_SOURCE
24
25#include <stdlib.h>
26#include <string.h>
27
28#include "access.h"
29#include "error.h"
30#include "data.h"
31#include "sensors.h"
32#include "../version.h"
33
34const char *libsensors_version = LM_VERSION;
35
36sensors_chip *sensors_config_chips = NULL;
37int sensors_config_chips_count = 0;
38int sensors_config_chips_max = 0;
39
40sensors_bus *sensors_config_busses = NULL;
41int sensors_config_busses_count = 0;
42int sensors_config_busses_max = 0;
43
44sensors_chip_features *sensors_proc_chips = NULL;
45int sensors_proc_chips_count = 0;
46int sensors_proc_chips_max = 0;
47
48sensors_bus *sensors_proc_bus = NULL;
49int sensors_proc_bus_count = 0;
50int sensors_proc_bus_max = 0;
51
52static int sensors_substitute_chip(sensors_chip_name *name, int lineno);
53
54/*
55   Parse a chip name to the internal representation. These are valid names:
56
57     lm78-i2c-10-5e             *-i2c-10-5e
58     lm78-i2c-10-*              *-i2c-10-*
59     lm78-i2c-*-5e              *-i2c-*-5e
60     lm78-i2c-*-*               *-i2c-*-*
61     lm78-isa-10dd              *-isa-10dd
62     lm78-isa-*                 *-isa-*
63     lm78-*                     *-*
64
65   Here 'lm78' can be any prefix. 'i2c' and 'isa' are
66   literal strings, just like all dashes '-' and wildcards '*'. '10' can
67   be any decimal i2c bus number. '5e' can be any hexadecimal i2c device
68   address, and '10dd' any hexadecimal isa address.
69
70   The 'prefix' part in the result is freshly allocated. All old contents
71   of res is overwritten. res itself is not allocated. In case of an error
72   return (ie. != 0), res is undefined, but all allocations are undone.
73*/
74
75int sensors_parse_chip_name(const char *name, sensors_chip_name *res)
76{
77        char *dash;
78
79        /* First, the prefix. It's either "*" or a real chip name. */
80        if (!strncmp(name, "*-", 2)) {
81                res->prefix = SENSORS_CHIP_NAME_PREFIX_ANY;
82                name += 2;
83        } else {
84                if (!(dash = strchr(name, '-')))
85                        return -SENSORS_ERR_CHIP_NAME;
86                res->prefix = strndup(name, dash - name);
87                if (!res->prefix)
88                        sensors_fatal_error("sensors_parse_chip_name",
89                                            "Allocating name prefix");
90                name = dash + 1;
91        }
92
93        /* Then we have either a sole "*" (all chips with this name) or a bus
94           type and an address. */
95        if (!strcmp(name, "*")) {
96                res->bus.type = SENSORS_BUS_TYPE_ANY;
97                res->bus.nr = SENSORS_BUS_NR_ANY;
98                res->addr = SENSORS_CHIP_NAME_ADDR_ANY;
99                return 0;
100        }
101
102        if (!(dash = strchr(name, '-')))
103                goto ERROR;
104        if (!strncmp(name, "i2c", dash - name))
105                res->bus.type = SENSORS_BUS_TYPE_I2C;
106        else if (!strncmp(name, "isa", dash - name))
107                res->bus.type = SENSORS_BUS_TYPE_ISA;
108        else if (!strncmp(name, "pci", dash - name))
109                res->bus.type = SENSORS_BUS_TYPE_PCI;
110        else if (!strncmp(name, "spi", dash - name))
111                res->bus.type = SENSORS_BUS_TYPE_SPI;
112        else
113                goto ERROR;
114        name = dash + 1;
115
116        /* Some bus types (i2c, spi) have an additional bus number.
117           For these, the next part is either a "*" (any bus of that type)
118           or a decimal number. */
119        switch (res->bus.type) {
120        case SENSORS_BUS_TYPE_I2C:
121        case SENSORS_BUS_TYPE_SPI:
122                if (!strncmp(name, "*-", 2)) {
123                        res->bus.nr = SENSORS_BUS_NR_ANY;
124                        name += 2;
125                        break;
126                }
127
128                res->bus.nr = strtoul(name, &dash, 10);
129                if (*name == '\0' || *dash != '-' || res->bus.nr < 0)
130                        goto ERROR;
131                name = dash + 1;
132                break;
133        default:
134                res->bus.nr = SENSORS_BUS_NR_ANY;
135        }
136
137        /* Last part is the chip address, or "*" for any address. */
138        if (!strcmp(name, "*")) {
139                res->addr = SENSORS_CHIP_NAME_ADDR_ANY;
140        } else {
141                res->addr = strtoul(name, &dash, 16);
142                if (*name == '\0' || *dash != '\0' || res->addr < 0)
143                        goto ERROR;
144        }
145
146        return 0;
147
148ERROR:
149        free(res->prefix);
150        return -SENSORS_ERR_CHIP_NAME;
151}
152
153int sensors_snprintf_chip_name(char *str, size_t size,
154                               const sensors_chip_name *chip)
155{
156        if (sensors_chip_name_has_wildcards(chip))
157                return -SENSORS_ERR_WILDCARDS;
158
159        switch (chip->bus.type) {
160        case SENSORS_BUS_TYPE_ISA:
161                return snprintf(str, size, "%s-isa-%04x", chip->prefix,
162                                chip->addr);
163        case SENSORS_BUS_TYPE_PCI:
164                return snprintf(str, size, "%s-pci-%04x", chip->prefix,
165                                chip->addr);
166        case SENSORS_BUS_TYPE_I2C:
167                return snprintf(str, size, "%s-i2c-%hd-%02x", chip->prefix,
168                                chip->bus.nr, chip->addr);
169        case SENSORS_BUS_TYPE_SPI:
170                return snprintf(str, size, "%s-spi-%hd-%x", chip->prefix,
171                                chip->bus.nr, chip->addr);
172        }
173
174        return -SENSORS_ERR_CHIP_NAME;
175}
176
177int sensors_parse_bus_id(const char *name, sensors_bus_id *bus)
178{
179        char *endptr;
180
181        if (strncmp(name, "i2c-", 4)) {
182                return -SENSORS_ERR_BUS_NAME;
183        }
184        name += 4;
185        bus->type = SENSORS_BUS_TYPE_I2C;
186        bus->nr = strtoul(name, &endptr, 10);
187        if (*name == '\0' || *endptr != '\0' || bus->nr < 0)
188                return -SENSORS_ERR_BUS_NAME;
189        return 0;
190}
191
192int sensors_substitute_chip(sensors_chip_name *name, int lineno)
193{
194        int i, j;
195        for (i = 0; i < sensors_config_busses_count; i++)
196                if (sensors_config_busses[i].bus.type == name->bus.type &&
197                    sensors_config_busses[i].bus.nr == name->bus.nr)
198                        break;
199
200        if (i == sensors_config_busses_count) {
201                sensors_parse_error("Undeclared bus id referenced", lineno);
202                name->bus.nr = SENSORS_BUS_NR_IGNORE;
203                return -SENSORS_ERR_BUS_NAME;
204        }
205
206        /* Compare the adapter names */
207        for (j = 0; j < sensors_proc_bus_count; j++) {
208                if (!strcmp(sensors_config_busses[i].adapter,
209                            sensors_proc_bus[j].adapter)) {
210                        name->bus.nr = sensors_proc_bus[j].bus.nr;
211                        return 0;
212                }
213        }
214
215        /* We did not find a matching bus name, simply ignore this chip
216           config entry. */
217        name->bus.nr = SENSORS_BUS_NR_IGNORE;
218        return 0;
219}
220
221int sensors_substitute_busses(void)
222{
223        int err, i, j, lineno;
224        sensors_chip_name_list *chips;
225        int res = 0;
226
227        for (i = 0; i < sensors_config_chips_count; i++) {
228                lineno = sensors_config_chips[i].lineno;
229                chips = &sensors_config_chips[i].chips;
230                for (j = 0; j < chips->fits_count; j++) {
231                        /* We can only substitute if a specific bus number
232                           is given. */
233                        if (chips->fits[j].bus.nr == SENSORS_BUS_NR_ANY)
234                                continue;
235
236                        err = sensors_substitute_chip(&chips->fits[j], lineno);
237                        if (err)
238                                res = err;
239                }
240        }
241        return res;
242}
Note: See TracBrowser for help on using the browser.