Merge tag 'v3.10.61' into linux-linaro-lsk
[firefly-linux-kernel-4.4.55.git] / tools / gator / daemon / libsensors / data.c
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, 2009  Jean Delvare <khali@linux-fr.org>
5
6     This library is free software; you can redistribute it and/or
7     modify it under the terms of the GNU Lesser General Public
8     License as published by the Free Software Foundation; either
9     version 2.1 of the License, or (at your option) any later version.
10
11     This library 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 Lesser 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 file modified by ARM on Jan 23, 2013 to move version.h to the current directory. ***/
23
24 /* this define needed for strndup() */
25 #define _GNU_SOURCE
26
27 #include <stdlib.h>
28 #include <string.h>
29
30 #include "access.h"
31 #include "error.h"
32 #include "data.h"
33 #include "sensors.h"
34 #include "version.h"
35
36 const char *libsensors_version = LM_VERSION;
37
38 char **sensors_config_files = NULL;
39 int sensors_config_files_count = 0;
40 int sensors_config_files_max = 0;
41
42 sensors_chip *sensors_config_chips = NULL;
43 int sensors_config_chips_count = 0;
44 int sensors_config_chips_subst = 0;
45 int sensors_config_chips_max = 0;
46
47 sensors_bus *sensors_config_busses = NULL;
48 int sensors_config_busses_count = 0;
49 int sensors_config_busses_max = 0;
50
51 sensors_chip_features *sensors_proc_chips = NULL;
52 int sensors_proc_chips_count = 0;
53 int sensors_proc_chips_max = 0;
54
55 sensors_bus *sensors_proc_bus = NULL;
56 int sensors_proc_bus_count = 0;
57 int sensors_proc_bus_max = 0;
58
59 void sensors_free_chip_name(sensors_chip_name *chip)
60 {
61         free(chip->prefix);
62 }
63
64 /*
65    Parse a chip name to the internal representation. These are valid names:
66
67      lm78-i2c-10-5e             *-i2c-10-5e
68      lm78-i2c-10-*              *-i2c-10-*
69      lm78-i2c-*-5e              *-i2c-*-5e
70      lm78-i2c-*-*               *-i2c-*-*
71      lm78-isa-10dd              *-isa-10dd
72      lm78-isa-*                 *-isa-*
73      lm78-*                     *-*
74
75    Here 'lm78' can be any prefix. 'i2c' and 'isa' are
76    literal strings, just like all dashes '-' and wildcards '*'. '10' can
77    be any decimal i2c bus number. '5e' can be any hexadecimal i2c device
78    address, and '10dd' any hexadecimal isa address.
79
80    The 'prefix' part in the result is freshly allocated. All old contents
81    of res is overwritten. res itself is not allocated. In case of an error
82    return (ie. != 0), res is undefined, but all allocations are undone.
83 */
84
85 int sensors_parse_chip_name(const char *name, sensors_chip_name *res)
86 {
87         char *dash;
88
89         /* First, the prefix. It's either "*" or a real chip name. */
90         if (!strncmp(name, "*-", 2)) {
91                 res->prefix = SENSORS_CHIP_NAME_PREFIX_ANY;
92                 name += 2;
93         } else {
94                 if (!(dash = strchr(name, '-')))
95                         return -SENSORS_ERR_CHIP_NAME;
96                 res->prefix = strndup(name, dash - name);
97                 if (!res->prefix)
98                         sensors_fatal_error(__func__,
99                                             "Allocating name prefix");
100                 name = dash + 1;
101         }
102
103         /* Then we have either a sole "*" (all chips with this name) or a bus
104            type and an address. */
105         if (!strcmp(name, "*")) {
106                 res->bus.type = SENSORS_BUS_TYPE_ANY;
107                 res->bus.nr = SENSORS_BUS_NR_ANY;
108                 res->addr = SENSORS_CHIP_NAME_ADDR_ANY;
109                 return 0;
110         }
111
112         if (!(dash = strchr(name, '-')))
113                 goto ERROR;
114         if (!strncmp(name, "i2c", dash - name))
115                 res->bus.type = SENSORS_BUS_TYPE_I2C;
116         else if (!strncmp(name, "isa", dash - name))
117                 res->bus.type = SENSORS_BUS_TYPE_ISA;
118         else if (!strncmp(name, "pci", dash - name))
119                 res->bus.type = SENSORS_BUS_TYPE_PCI;
120         else if (!strncmp(name, "spi", dash - name))
121                 res->bus.type = SENSORS_BUS_TYPE_SPI;
122         else if (!strncmp(name, "virtual", dash - name))
123                 res->bus.type = SENSORS_BUS_TYPE_VIRTUAL;
124         else if (!strncmp(name, "acpi", dash - name))
125                 res->bus.type = SENSORS_BUS_TYPE_ACPI;
126         else if (!strncmp(name, "hid", dash - name))
127                 res->bus.type = SENSORS_BUS_TYPE_HID;
128         else
129                 goto ERROR;
130         name = dash + 1;
131
132         /* Some bus types (i2c, spi) have an additional bus number.
133            For these, the next part is either a "*" (any bus of that type)
134            or a decimal number. */
135         switch (res->bus.type) {
136         case SENSORS_BUS_TYPE_I2C:
137         case SENSORS_BUS_TYPE_SPI:
138         case SENSORS_BUS_TYPE_HID:
139                 if (!strncmp(name, "*-", 2)) {
140                         res->bus.nr = SENSORS_BUS_NR_ANY;
141                         name += 2;
142                         break;
143                 }
144
145                 res->bus.nr = strtoul(name, &dash, 10);
146                 if (*name == '\0' || *dash != '-' || res->bus.nr < 0)
147                         goto ERROR;
148                 name = dash + 1;
149                 break;
150         default:
151                 res->bus.nr = SENSORS_BUS_NR_ANY;
152         }
153
154         /* Last part is the chip address, or "*" for any address. */
155         if (!strcmp(name, "*")) {
156                 res->addr = SENSORS_CHIP_NAME_ADDR_ANY;
157         } else {
158                 res->addr = strtoul(name, &dash, 16);
159                 if (*name == '\0' || *dash != '\0' || res->addr < 0)
160                         goto ERROR;
161         }
162
163         return 0;
164
165 ERROR:
166         free(res->prefix);
167         return -SENSORS_ERR_CHIP_NAME;
168 }
169
170 int sensors_snprintf_chip_name(char *str, size_t size,
171                                const sensors_chip_name *chip)
172 {
173         if (sensors_chip_name_has_wildcards(chip))
174                 return -SENSORS_ERR_WILDCARDS;
175
176         switch (chip->bus.type) {
177         case SENSORS_BUS_TYPE_ISA:
178                 return snprintf(str, size, "%s-isa-%04x", chip->prefix,
179                                 chip->addr);
180         case SENSORS_BUS_TYPE_PCI:
181                 return snprintf(str, size, "%s-pci-%04x", chip->prefix,
182                                 chip->addr);
183         case SENSORS_BUS_TYPE_I2C:
184                 return snprintf(str, size, "%s-i2c-%hd-%02x", chip->prefix,
185                                 chip->bus.nr, chip->addr);
186         case SENSORS_BUS_TYPE_SPI:
187                 return snprintf(str, size, "%s-spi-%hd-%x", chip->prefix,
188                                 chip->bus.nr, chip->addr);
189         case SENSORS_BUS_TYPE_VIRTUAL:
190                 return snprintf(str, size, "%s-virtual-%x", chip->prefix,
191                                 chip->addr);
192         case SENSORS_BUS_TYPE_ACPI:
193                 return snprintf(str, size, "%s-acpi-%x", chip->prefix,
194                                 chip->addr);
195         case SENSORS_BUS_TYPE_HID:
196                 return snprintf(str, size, "%s-hid-%hd-%x", chip->prefix,
197                                 chip->bus.nr, chip->addr);
198         }
199
200         return -SENSORS_ERR_CHIP_NAME;
201 }
202
203 int sensors_parse_bus_id(const char *name, sensors_bus_id *bus)
204 {
205         char *endptr;
206
207         if (strncmp(name, "i2c-", 4)) {
208                 return -SENSORS_ERR_BUS_NAME;
209         }
210         name += 4;
211         bus->type = SENSORS_BUS_TYPE_I2C;
212         bus->nr = strtoul(name, &endptr, 10);
213         if (*name == '\0' || *endptr != '\0' || bus->nr < 0)
214                 return -SENSORS_ERR_BUS_NAME;
215         return 0;
216 }
217
218 static int sensors_substitute_chip(sensors_chip_name *name,
219                                    const char *filename, int lineno)
220 {
221         int i, j;
222         for (i = 0; i < sensors_config_busses_count; i++)
223                 if (sensors_config_busses[i].bus.type == name->bus.type &&
224                     sensors_config_busses[i].bus.nr == name->bus.nr)
225                         break;
226
227         if (i == sensors_config_busses_count) {
228                 sensors_parse_error_wfn("Undeclared bus id referenced",
229                                         filename, lineno);
230                 name->bus.nr = SENSORS_BUS_NR_IGNORE;
231                 return -SENSORS_ERR_BUS_NAME;
232         }
233
234         /* Compare the adapter names */
235         for (j = 0; j < sensors_proc_bus_count; j++) {
236                 if (!strcmp(sensors_config_busses[i].adapter,
237                             sensors_proc_bus[j].adapter)) {
238                         name->bus.nr = sensors_proc_bus[j].bus.nr;
239                         return 0;
240                 }
241         }
242
243         /* We did not find a matching bus name, simply ignore this chip
244            config entry. */
245         name->bus.nr = SENSORS_BUS_NR_IGNORE;
246         return 0;
247 }
248
249 /* Bus substitution is on a per-configuration file basis, so we keep
250    memory (in sensors_config_chips_subst) of which chip entries have been
251    already substituted. */
252 int sensors_substitute_busses(void)
253 {
254         int err, i, j, lineno;
255         sensors_chip_name_list *chips;
256         const char *filename;
257         int res = 0;
258
259         for (i = sensors_config_chips_subst;
260              i < sensors_config_chips_count; i++) {
261                 filename = sensors_config_chips[i].line.filename;
262                 lineno = sensors_config_chips[i].line.lineno;
263                 chips = &sensors_config_chips[i].chips;
264                 for (j = 0; j < chips->fits_count; j++) {
265                         /* We can only substitute if a specific bus number
266                            is given. */
267                         if (chips->fits[j].bus.nr == SENSORS_BUS_NR_ANY)
268                                 continue;
269
270                         err = sensors_substitute_chip(&chips->fits[j],
271                                                       filename, lineno);
272                         if (err)
273                                 res = err;
274                 }
275         }
276         sensors_config_chips_subst = sensors_config_chips_count;
277         return res;
278 }