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>
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.
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.
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,
22 /*** This file modified by ARM on Jan 23, 2013 to move version.h to the current directory. ***/
24 /* this define needed for strndup() */
36 const char *libsensors_version = LM_VERSION;
38 char **sensors_config_files = NULL;
39 int sensors_config_files_count = 0;
40 int sensors_config_files_max = 0;
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;
47 sensors_bus *sensors_config_busses = NULL;
48 int sensors_config_busses_count = 0;
49 int sensors_config_busses_max = 0;
51 sensors_chip_features *sensors_proc_chips = NULL;
52 int sensors_proc_chips_count = 0;
53 int sensors_proc_chips_max = 0;
55 sensors_bus *sensors_proc_bus = NULL;
56 int sensors_proc_bus_count = 0;
57 int sensors_proc_bus_max = 0;
59 void sensors_free_chip_name(sensors_chip_name *chip)
65 Parse a chip name to the internal representation. These are valid names:
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
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.
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.
85 int sensors_parse_chip_name(const char *name, sensors_chip_name *res)
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;
94 if (!(dash = strchr(name, '-')))
95 return -SENSORS_ERR_CHIP_NAME;
96 res->prefix = strndup(name, dash - name);
98 sensors_fatal_error(__func__,
99 "Allocating name prefix");
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;
112 if (!(dash = strchr(name, '-')))
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;
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;
145 res->bus.nr = strtoul(name, &dash, 10);
146 if (*name == '\0' || *dash != '-' || res->bus.nr < 0)
151 res->bus.nr = SENSORS_BUS_NR_ANY;
154 /* Last part is the chip address, or "*" for any address. */
155 if (!strcmp(name, "*")) {
156 res->addr = SENSORS_CHIP_NAME_ADDR_ANY;
158 res->addr = strtoul(name, &dash, 16);
159 if (*name == '\0' || *dash != '\0' || res->addr < 0)
167 return -SENSORS_ERR_CHIP_NAME;
170 int sensors_snprintf_chip_name(char *str, size_t size,
171 const sensors_chip_name *chip)
173 if (sensors_chip_name_has_wildcards(chip))
174 return -SENSORS_ERR_WILDCARDS;
176 switch (chip->bus.type) {
177 case SENSORS_BUS_TYPE_ISA:
178 return snprintf(str, size, "%s-isa-%04x", chip->prefix,
180 case SENSORS_BUS_TYPE_PCI:
181 return snprintf(str, size, "%s-pci-%04x", chip->prefix,
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,
192 case SENSORS_BUS_TYPE_ACPI:
193 return snprintf(str, size, "%s-acpi-%x", chip->prefix,
195 case SENSORS_BUS_TYPE_HID:
196 return snprintf(str, size, "%s-hid-%hd-%x", chip->prefix,
197 chip->bus.nr, chip->addr);
200 return -SENSORS_ERR_CHIP_NAME;
203 int sensors_parse_bus_id(const char *name, sensors_bus_id *bus)
207 if (strncmp(name, "i2c-", 4)) {
208 return -SENSORS_ERR_BUS_NAME;
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;
218 static int sensors_substitute_chip(sensors_chip_name *name,
219 const char *filename, int lineno)
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)
227 if (i == sensors_config_busses_count) {
228 sensors_parse_error_wfn("Undeclared bus id referenced",
230 name->bus.nr = SENSORS_BUS_NR_IGNORE;
231 return -SENSORS_ERR_BUS_NAME;
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;
243 /* We did not find a matching bus name, simply ignore this chip
245 name->bus.nr = SENSORS_BUS_NR_IGNORE;
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)
254 int err, i, j, lineno;
255 sensors_chip_name_list *chips;
256 const char *filename;
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
267 if (chips->fits[j].bus.nr == SENSORS_BUS_NR_ANY)
270 err = sensors_substitute_chip(&chips->fits[j],
276 sensors_config_chips_subst = sensors_config_chips_count;