Bug Summary

File:dev/i2c/adt7460.c
Warning:line 315, column 35
The left operand of '*' is a garbage value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name adt7460.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model static -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -ffreestanding -mcmodel=kernel -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -target-feature -sse2 -target-feature -sse -target-feature -3dnow -target-feature -mmx -target-feature +save-args -disable-red-zone -no-implicit-float -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -nostdsysteminc -nobuiltininc -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/sys -I /usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -I /usr/src/sys/arch -I /usr/src/sys/dev/pci/drm/include -I /usr/src/sys/dev/pci/drm/include/uapi -I /usr/src/sys/dev/pci/drm/amd/include/asic_reg -I /usr/src/sys/dev/pci/drm/amd/include -I /usr/src/sys/dev/pci/drm/amd/amdgpu -I /usr/src/sys/dev/pci/drm/amd/display -I /usr/src/sys/dev/pci/drm/amd/display/include -I /usr/src/sys/dev/pci/drm/amd/display/dc -I /usr/src/sys/dev/pci/drm/amd/display/amdgpu_dm -I /usr/src/sys/dev/pci/drm/amd/pm/inc -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu11 -I /usr/src/sys/dev/pci/drm/amd/pm/swsmu/smu12 -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/hwmgr -I /usr/src/sys/dev/pci/drm/amd/pm/powerplay/smumgr -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc -I /usr/src/sys/dev/pci/drm/amd/display/dc/inc/hw -I /usr/src/sys/dev/pci/drm/amd/display/dc/clk_mgr -I /usr/src/sys/dev/pci/drm/amd/display/modules/inc -I /usr/src/sys/dev/pci/drm/amd/display/modules/hdcp -I /usr/src/sys/dev/pci/drm/amd/display/dmub/inc -I /usr/src/sys/dev/pci/drm/i915 -D DDB -D DIAGNOSTIC -D KTRACE -D ACCOUNTING -D KMEMSTATS -D PTRACE -D POOL_DEBUG -D CRYPTO -D SYSVMSG -D SYSVSEM -D SYSVSHM -D UVM_SWAP_ENCRYPT -D FFS -D FFS2 -D FFS_SOFTUPDATES -D UFS_DIRHASH -D QUOTA -D EXT2FS -D MFS -D NFSCLIENT -D NFSSERVER -D CD9660 -D UDF -D MSDOSFS -D FIFO -D FUSE -D SOCKET_SPLICE -D TCP_ECN -D TCP_SIGNATURE -D INET6 -D IPSEC -D PPP_BSDCOMP -D PPP_DEFLATE -D PIPEX -D MROUTING -D MPLS -D BOOT_CONFIG -D USER_PCICONF -D APERTURE -D MTRR -D NTFS -D HIBERNATE -D PCIVERBOSE -D USBVERBOSE -D WSDISPLAY_COMPAT_USL -D WSDISPLAY_COMPAT_RAWKBD -D WSDISPLAY_DEFAULTSCREENS=6 -D X86EMU -D ONEWIREVERBOSE -D MULTIPROCESSOR -D MAXUSERS=80 -D _KERNEL -D CONFIG_DRM_AMD_DC_DCN3_0 -O2 -Wno-pointer-sign -Wno-address-of-packed-member -Wno-constant-conversion -Wno-unused-but-set-variable -Wno-gnu-folding-constant -fdebug-compilation-dir=/usr/src/sys/arch/amd64/compile/GENERIC.MP/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -o /usr/obj/sys/arch/amd64/compile/GENERIC.MP/scan-build/2022-01-12-131800-47421-1 -x c /usr/src/sys/dev/i2c/adt7460.c
1/* $OpenBSD: adt7460.c,v 1.21 2007/12/12 16:56:59 deraadt Exp $ */
2
3/*
4 * Copyright (c) 2005 Mark Kettenis
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <sys/param.h>
20#include <sys/systm.h>
21#include <sys/device.h>
22#include <sys/sensors.h>
23
24#include <dev/i2c/i2cvar.h>
25
26/* ADT7460 registers */
27#define ADT7460_2_5V0x20 0x20
28#define ADT7460_VCCP0x21 0x21
29#define ADT7460_VCC0x22 0x22
30#define ADT7460_V50x23 0x23
31#define ADT7460_V120x24 0x24
32#define ADT7460_VTR0x99 0x99
33#define ADT7460_VBAT0x9a 0x9a
34#define ADT7460_REM1_TEMP0x25 0x25
35#define ADT7460_LOCAL_TEMP0x26 0x26
36#define ADT7460_REM2_TEMP0x27 0x27
37#define ADT7460_TACH1L0x28 0x28
38#define ADT7460_TACH1H0x29 0x29
39#define ADT7460_TACH2L0x2a 0x2a
40#define ADT7460_TACH2H0x2b 0x2b
41#define ADT7460_TACH3L0x2c 0x2c
42#define ADT7460_TACH3H0x2d 0x2d
43#define ADT7460_TACH4L0x2e 0x2e
44#define ADT7460_TACH4H0x2f 0x2f
45#define ADT7460_TACH5L0xa9 0xa9
46#define ADT7460_TACH5H0xaa 0xaa
47#define ADT7460_TACH6L0xab 0xab
48#define ADT7460_TACH6H0xac 0xac
49#define ADT7460_REVISION0x3f 0x3f
50#define ADT7460_CONFIG0x40 0x40
51#define ADT7460_CONFIG_Vcc0x80 0x80
52
53/* Sensors */
54#define ADT_2_5V0 0
55#define ADT_VCCP1 1
56#define ADT_VCC2 2
57#define ADT_V53 3
58#define ADT_V124 4
59#define ADT_VTR5 5
60#define ADT_VBAT6 6
61#define ADT_REM1_TEMP7 7
62#define ADT_LOCAL_TEMP8 8
63#define ADT_REM2_TEMP9 9
64#define ADT_TACH110 10
65#define ADT_TACH211 11
66#define ADT_TACH312 12
67#define ADT_TACH413 13
68#define ADT_TACH514 14
69#define ADT_TACH615 15
70#define ADT_NUM_SENSORS16 16
71
72struct adt_chip {
73 const char *name;
74 short ratio[7];
75 int type;
76 short vcc;
77} adt_chips[] = {
78 /* register 0x20 0x21 0x22 0x23 0x24 0xa8 0xaa type */
79 /* 2.5v vccp vcc 5v 12v vtr vbat */
80
81 { "adt7460", { 2500, 0, 3300, 0, 0, 0, 0 }, 7460, 5000 },
82 { "adt7467", { 2500, 2250, 3300, 5000, 12000, 0, 0 }, 7467, 5000 },
83 { "adt7475", { 0, 2250, 3300, 0, 0, 0, 0 }, 7475, 0 },
84 { "adt7476", { 2500, 2250, 3300, 5000, 12000, 0, 0 }, 7476, 0 },
85 { "adm1027", { 2500, 2250, 3300, 5000, 12000, 0, 0 }, 1027, 5000 },
86 { "lm85", { 2500, 2250, 3300, 5000, 12000, 0, 0 }, 7467, 0 },
87 { "emc6d100", { 2500, 2250, 3300, 5000, 12000, 0, 0 }, 6100, 0 },
88 { "emc6w201", { 2500, 2250, 3300, 5000, 12000, 0, 0 }, 6201, 0 },
89 { "lm96000", { 2500, 2250, 3300, 5000, 12000, 0, 0 }, 96000, 0 },
90 { "sch5017", { 5000, 2250, 3300, 5000, 12000, 0, 0 }, 5017, 0 },
91 { "sch5027", { 5000, 2250, 3300, 5000, 12000, 3300, 3300 }, 5027, 0 }
92};
93
94struct {
95 char sensor;
96 u_int8_t cmd;
97 u_short index;
98} worklist[] = {
99 { ADT_2_5V0, ADT7460_2_5V0x20, 32768 + 0 },
100 { ADT_VCCP1, ADT7460_VCCP0x21, 32768 + 1 },
101 { ADT_VCC2, ADT7460_VCC0x22, 32768 + 2 },
102 { ADT_V53, ADT7460_V50x23, 32768 + 3 },
103 { ADT_V124, ADT7460_V120x24, 32768 + 4 },
104 { ADT_VTR5, ADT7460_VTR0x99, 32768 + 5 },
105 { ADT_VBAT6, ADT7460_VBAT0x9a, 32768 + 6 },
106 { ADT_REM1_TEMP7, ADT7460_REM1_TEMP0x25 },
107 { ADT_LOCAL_TEMP8, ADT7460_LOCAL_TEMP0x26 },
108 { ADT_REM2_TEMP9, ADT7460_REM2_TEMP0x27 },
109 { ADT_TACH110, ADT7460_TACH1L0x28 },
110 { ADT_TACH211, ADT7460_TACH2L0x2a },
111 { ADT_TACH312, ADT7460_TACH3L0x2c },
112 { ADT_TACH413, ADT7460_TACH4L0x2e },
113 { ADT_TACH514, ADT7460_TACH5L0xa9 },
114 { ADT_TACH615, ADT7460_TACH6L0xab },
115};
116
117struct adt_softc {
118 struct device sc_dev;
119 i2c_tag_t sc_tag;
120 i2c_addr_t sc_addr;
121 u_int8_t sc_conf;
122 struct adt_chip *chip;
123
124 struct ksensor sc_sensor[ADT_NUM_SENSORS16];
125 struct ksensordev sc_sensordev;
126};
127
128int adt_match(struct device *, void *, void *);
129void adt_attach(struct device *, struct device *, void *);
130
131void adt_refresh(void *);
132
133struct cfattach adt_ca = {
134 sizeof(struct adt_softc), adt_match, adt_attach
135};
136
137struct cfdriver adt_cd = {
138 NULL((void *)0), "adt", DV_DULL
139};
140
141int
142adt_match(struct device *parent, void *match, void *aux)
143{
144 struct i2c_attach_args *ia = aux;
145 int i;
146
147 for (i = 0; i < sizeof(adt_chips) / sizeof(adt_chips[0]); i++)
148 if (strcmp(ia->ia_name, adt_chips[i].name) == 0)
149 return (1);
150 return (0);
151}
152
153void
154adt_attach(struct device *parent, struct device *self, void *aux)
155{
156 struct adt_softc *sc = (struct adt_softc *)self;
157 struct i2c_attach_args *ia = aux;
158 u_int8_t cmd, rev, data;
159 int i;
160
161 sc->sc_tag = ia->ia_tag;
162 sc->sc_addr = ia->ia_addr;
163
164 iic_acquire_bus(sc->sc_tag, 0)(*(sc->sc_tag)->ic_acquire_bus)((sc->sc_tag)->ic_cookie
, (0))
;
165
166 for (i = 0; i < sizeof(adt_chips) / sizeof(adt_chips[0]); i++) {
167 if (strcmp(ia->ia_name, adt_chips[i].name) == 0) {
168 sc->chip = &adt_chips[i];
169 break;
170 }
171 }
172
173 cmd = ADT7460_REVISION0x3f;
174 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
175 sc->sc_addr, &cmd, sizeof cmd, &rev, sizeof rev, 0)) {
176 iic_release_bus(sc->sc_tag, 0)(*(sc->sc_tag)->ic_release_bus)((sc->sc_tag)->ic_cookie
, (0))
;
177 printf(": cannot read REV register\n");
178 return;
179 }
180
181 cmd = ADT7460_CONFIG0x40;
182 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
183 sc->sc_addr, &cmd, sizeof cmd, &sc->sc_conf, sizeof sc->sc_conf, 0)) {
184 iic_release_bus(sc->sc_tag, 0)(*(sc->sc_tag)->ic_release_bus)((sc->sc_tag)->ic_cookie
, (0))
;
185 printf(": cannot read config register\n");
186 return;
187 }
188
189 if (sc->chip->type == 7460) {
190 data = 1;
191 cmd = ADT7460_CONFIG0x40;
192 if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP,
193 sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0)) {
194 iic_release_bus(sc->sc_tag, 0)(*(sc->sc_tag)->ic_release_bus)((sc->sc_tag)->ic_cookie
, (0))
;
195 printf(": cannot set control register\n");
196 return;
197 }
198 }
199
200 iic_release_bus(sc->sc_tag, 0)(*(sc->sc_tag)->ic_release_bus)((sc->sc_tag)->ic_cookie
, (0))
;
201
202 printf(": %s rev 0x%02x", ia->ia_name, rev);
203
204 /* Initialize sensor data. */
205 strlcpy(sc->sc_sensordev.xname, sc->sc_dev.dv_xname,
206 sizeof(sc->sc_sensordev.xname));
207
208 sc->sc_sensor[ADT_2_5V0].type = SENSOR_VOLTS_DC;
209 strlcpy(sc->sc_sensor[ADT_2_5V0].desc, "+2.5Vin",
210 sizeof(sc->sc_sensor[ADT_2_5V0].desc));
211
212 if (sc->chip->type == 5017)
213 strlcpy(sc->sc_sensor[ADT_2_5V0].desc, "+5VTR",
214 sizeof(sc->sc_sensor[ADT_2_5V0].desc));
215 if (sc->chip->type == 5027)
216 strlcpy(sc->sc_sensor[ADT_2_5V0].desc, "+5V",
217 sizeof(sc->sc_sensor[ADT_2_5V0].desc));
218
219 sc->sc_sensor[ADT_VCCP1].type = SENSOR_VOLTS_DC;
220 strlcpy(sc->sc_sensor[ADT_VCCP1].desc, "Vccp",
221 sizeof(sc->sc_sensor[ADT_VCCP1].desc));
222
223 sc->sc_sensor[ADT_VCC2].type = SENSOR_VOLTS_DC;
224 strlcpy(sc->sc_sensor[ADT_VCC2].desc, "Vcc",
225 sizeof(sc->sc_sensor[ADT_VCC2].desc));
226
227 sc->sc_sensor[ADT_V53].type = SENSOR_VOLTS_DC;
228 strlcpy(sc->sc_sensor[ADT_V53].desc, "+5V",
229 sizeof(sc->sc_sensor[ADT_V53].desc));
230
231 sc->sc_sensor[ADT_V124].type = SENSOR_VOLTS_DC;
232 strlcpy(sc->sc_sensor[ADT_V124].desc, "+12V",
233 sizeof(sc->sc_sensor[ADT_V124].desc));
234
235 sc->sc_sensor[ADT_VTR5].type = SENSOR_VOLTS_DC;
236 strlcpy(sc->sc_sensor[ADT_VTR5].desc, "+Vtr",
237 sizeof(sc->sc_sensor[ADT_VTR5].desc));
238
239 sc->sc_sensor[ADT_VBAT6].type = SENSOR_VOLTS_DC;
240 strlcpy(sc->sc_sensor[ADT_VBAT6].desc, "+Vbat",
241 sizeof(sc->sc_sensor[ADT_VBAT6].desc));
242
243 sc->sc_sensor[ADT_REM1_TEMP7].type = SENSOR_TEMP;
244 strlcpy(sc->sc_sensor[ADT_REM1_TEMP7].desc, "Remote",
245 sizeof(sc->sc_sensor[ADT_REM1_TEMP7].desc));
246
247 sc->sc_sensor[ADT_LOCAL_TEMP8].type = SENSOR_TEMP;
248 strlcpy(sc->sc_sensor[ADT_LOCAL_TEMP8].desc, "Internal",
249 sizeof(sc->sc_sensor[ADT_LOCAL_TEMP8].desc));
250
251 sc->sc_sensor[ADT_REM2_TEMP9].type = SENSOR_TEMP;
252 strlcpy(sc->sc_sensor[ADT_REM2_TEMP9].desc, "Remote",
253 sizeof(sc->sc_sensor[ADT_REM2_TEMP9].desc));
254
255 sc->sc_sensor[ADT_TACH110].type = SENSOR_FANRPM;
256 sc->sc_sensor[ADT_TACH211].type = SENSOR_FANRPM;
257 sc->sc_sensor[ADT_TACH312].type = SENSOR_FANRPM;
258 sc->sc_sensor[ADT_TACH413].type = SENSOR_FANRPM;
259 sc->sc_sensor[ADT_TACH514].type = SENSOR_FANRPM;
260 sc->sc_sensor[ADT_TACH615].type = SENSOR_FANRPM;
261
262 if (sensor_task_register(sc, adt_refresh, 5) == NULL((void *)0)) {
263 printf(", unable to register update task\n");
264 return;
265 }
266
267 for (i = 0; i < ADT_NUM_SENSORS16; i++) {
268 if (worklist[i].index >= 32768 &&
269 sc->chip->ratio[worklist[i].index - 32768] == 0)
270 continue;
271 sensor_attach(&sc->sc_sensordev, &sc->sc_sensor[i]);
272 }
273 sensordev_install(&sc->sc_sensordev);
274
275
276 printf("\n");
277}
278
279void
280adt_refresh(void *arg)
281{
282 struct adt_softc *sc = arg;
283 u_int8_t cmd, data, data2;
284 u_int16_t fan;
285 int i, ratio;
1
'ratio' declared without an initial value
286
287 iic_acquire_bus(sc->sc_tag, 0)(*(sc->sc_tag)->ic_acquire_bus)((sc->sc_tag)->ic_cookie
, (0))
;
288
289 for (i = 0; i < sizeof worklist / sizeof(worklist[0]); i++) {
2
Loop condition is true. Entering loop body
290
291 if (worklist[i].index >= 32768) {
3
Assuming field 'index' is < 32768
4
Taking false branch
292 ratio = sc->chip->ratio[worklist[i].index - 32768];
293 if (ratio == 0) /* do not read a dead register */
294 continue;
295 }
296 cmd = worklist[i].cmd;
297 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
5
Assuming the condition is false
6
Taking false branch
298 sc->sc_addr, &cmd, sizeof cmd, &data, sizeof data, 0)) {
299 sc->sc_sensor[i].flags |= SENSOR_FINVALID0x0001;
300 continue;
301 }
302
303 sc->sc_sensor[i].flags &= ~SENSOR_FINVALID0x0001;
304 switch (worklist[i].sensor) {
7
Control jumps to 'case 6:' at line 314
305 case ADT_VCC2:
306 if (sc->chip->vcc && (sc->sc_conf & ADT7460_CONFIG_Vcc0x80))
307 ratio = sc->chip->vcc;
308 /* FALLTHROUGH */
309 case ADT_2_5V0:
310 case ADT_VCCP1:
311 case ADT_V53:
312 case ADT_V124:
313 case ADT_VTR5:
314 case ADT_VBAT6:
315 sc->sc_sensor[i].value = ratio * 1000 * (u_int)data / 192;
8
The left operand of '*' is a garbage value
316 break;
317 case ADT_LOCAL_TEMP8:
318 case ADT_REM1_TEMP7:
319 case ADT_REM2_TEMP9:
320 if (data == 0x80)
321 sc->sc_sensor[i].flags |= SENSOR_FINVALID0x0001;
322 else
323 sc->sc_sensor[i].value =
324 (int8_t)data * 1000000 + 273150000;
325 break;
326 case ADT_TACH110:
327 case ADT_TACH211:
328 case ADT_TACH312:
329 case ADT_TACH413:
330 cmd = worklist[i].cmd + 1; /* TACHnH follows TACHnL */
331 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
332 sc->sc_addr, &cmd, sizeof cmd, &data2, sizeof data2, 0)) {
333 sc->sc_sensor[i].flags |= SENSOR_FINVALID0x0001;
334 continue;
335 }
336
337 fan = data + (data2 << 8);
338 if (fan == 0 || fan == 0xffff)
339 sc->sc_sensor[i].flags |= SENSOR_FINVALID0x0001;
340 else
341 sc->sc_sensor[i].value = (90000 * 60) / fan;
342 break;
343 case ADT_TACH514:
344 case ADT_TACH615:
345 if (sc->chip->type != 5027) {
346 sc->sc_sensor[i].flags |= SENSOR_FINVALID0x0001;
347 break; /* only 5027 has these fans? */
348 }
349 cmd = worklist[i].cmd + 1; /* TACHnH follows TACHnL */
350 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP,
351 sc->sc_addr, &cmd, sizeof cmd, &data2, sizeof data2, 0)) {
352 sc->sc_sensor[i].flags |= SENSOR_FINVALID0x0001;
353 continue;
354 }
355
356 fan = data + (data2 << 8);
357 if (fan == 0 || fan == 0xffff)
358 sc->sc_sensor[i].flags |= SENSOR_FINVALID0x0001;
359 else
360 sc->sc_sensor[i].value = fan * 60;
361 break;
362 default:
363 sc->sc_sensor[i].flags |= SENSOR_FINVALID0x0001;
364 break;
365 }
366 }
367
368 iic_release_bus(sc->sc_tag, 0)(*(sc->sc_tag)->ic_release_bus)((sc->sc_tag)->ic_cookie
, (0))
;
369}