Bug Summary

File:dev/usb/uoakv.c
Warning:line 237, column 2
Value stored to 'frame' is never read

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 uoakv.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/usb/uoakv.c
1/* $OpenBSD: uoakv.c,v 1.16 2022/01/09 05:43:02 jsg Exp $ */
2
3/*
4 * Copyright (c) 2012 Yojiro UO <yuo@nui.org>
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 DISCAIMS 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/* TORADEX OAK series sensors: 8channel +/-10V ADC driver */
20/* http://developer.toradex.com/files/toradex-dev/uploads/media/Oak/Oak_ProgrammingGuide.pdf */
21
22#include <sys/param.h>
23#include <sys/systm.h>
24#include <sys/kernel.h>
25#include <sys/malloc.h>
26#include <sys/device.h>
27#include <sys/conf.h>
28#include <sys/sensors.h>
29
30#include <dev/usb/usb.h>
31#include <dev/usb/usbhid.h>
32#include <dev/usb/usbdi.h>
33#include <dev/usb/usbdevs.h>
34#include <dev/usb/uhidev.h>
35
36#include "uoak.h"
37
38#ifdef UOAKV_DEBUG
39int uoakvdebug = 0;
40#define DPRINTFN(n, x) do { if (uoakvdebug > (n)) printf x; } while (0)
41#else
42#define DPRINTFN(n, x)
43#endif
44
45#define DPRINTF(x) DPRINTFN(0, x)
46
47#define UOAKV_SAMPLE_RATE100 100 /* ms */
48#define UOAKV_REFRESH_PERIOD1 1 /* 1 sec : 1Hz */
49
50struct uoakv_sensor {
51 struct uoak_sensor v;
52 /* ADC setting */
53 unsigned int offset[OAK_V_TARGET_MAX2]; /* absolute offset (mV) */
54};
55
56struct uoakv_softc {
57 struct uhidev sc_hdev;
58
59 /* uoak common */
60 struct uoak_softc sc_uoak_softc;
61
62 /* sensor framework */
63 struct uoakv_sensor sc_sensor[OAK_V_MAXSENSORS8];
64 struct ksensordev sc_sensordev;
65 struct sensor_task *sc_sensortask;
66
67 /* sensor setting */
68 int sc_inputmode[OAK_V_TARGET_MAX2];
69
70};
71
72const struct usb_devno uoakv_devs[] = {
73 { USB_VENDOR_TORADEX0x1b67, USB_PRODUCT_TORADEX_10V0x000e},
74};
75#define uoakv_lookup(v, p)usbd_match_device((const struct usb_devno *)(uoakv_devs), sizeof
(uoakv_devs) / sizeof ((uoakv_devs)[0]), sizeof ((uoakv_devs
)[0]), (v), (p))
usb_lookup(uoakv_devs, v, p)usbd_match_device((const struct usb_devno *)(uoakv_devs), sizeof
(uoakv_devs) / sizeof ((uoakv_devs)[0]), sizeof ((uoakv_devs
)[0]), (v), (p))
76
77int uoakv_match(struct device *, void *, void *);
78void uoakv_attach(struct device *, struct device *, void *);
79int uoakv_detach(struct device *, int);
80
81void uoakv_intr(struct uhidev *, void *, u_int);
82void uoakv_refresh(void *);
83
84int uoakv_get_channel_setting(struct uoakv_softc *, enum uoak_target, int);
85int uoakv_get_sensor_setting(struct uoakv_softc *, enum uoak_target);
86
87void uoakv_dev_setting(void *, enum uoak_target);
88void uoakv_dev_print(void *, enum uoak_target);
89
90
91struct cfdriver uoakv_cd = {
92 NULL((void *)0), "uoakv", DV_DULL
93};
94
95const struct cfattach uoakv_ca = {
96 sizeof(struct uoakv_softc),
97 uoakv_match,
98 uoakv_attach,
99 uoakv_detach,
100
101};
102
103struct uoak_methods uoakv_methods = {
104 uoakv_dev_print,
105 uoakv_dev_setting
106};
107
108int
109uoakv_match(struct device *parent, void *match, void *aux)
110{
111 struct uhidev_attach_arg *uha = aux;
112
113 if (UHIDEV_CLAIM_MULTIPLE_REPORTID(uha)((uha)->claimed != ((void *)0)))
114 return (UMATCH_NONE0);
115
116 if (uoakv_lookup(uha->uaa->vendor, uha->uaa->product)usbd_match_device((const struct usb_devno *)(uoakv_devs), sizeof
(uoakv_devs) / sizeof ((uoakv_devs)[0]), sizeof ((uoakv_devs
)[0]), (uha->uaa->vendor), (uha->uaa->product))
== NULL((void *)0))
117 return UMATCH_NONE0;
118
119 return (UMATCH_VENDOR_PRODUCT13);
120}
121
122void
123uoakv_attach(struct device *parent, struct device *self, void *aux)
124{
125 struct uoakv_softc *sc = (struct uoakv_softc *)self;
126 struct usb_attach_arg *uaa = aux;
127 struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)uaa;
128 struct usbd_device *dev = uha->parent->sc_udev;
129
130 struct uoak_softc *scc = &sc->sc_uoak_softc;
131 int i, err, size, repid;
132 void *desc;
133
134 sc->sc_hdev.sc_intr = uoakv_intr;
135 sc->sc_hdev.sc_parent = uha->parent;
136 sc->sc_hdev.sc_report_id = uha->reportid;
137
138 scc->sc_parent = sc;
139 scc->sc_udev = dev;
140 scc->sc_hdev = &sc->sc_hdev;
141 scc->sc_methods = &uoakv_methods;
142 scc->sc_sensordev = &sc->sc_sensordev;
143
144 uhidev_get_report_desc(uha->parent, &desc, &size);
145 repid = uha->reportid;
146 scc->sc_ilen = hid_report_size(desc, size, hid_input, repid);
147 scc->sc_olen = hid_report_size(desc, size, hid_output, repid);
148 scc->sc_flen = hid_report_size(desc, size, hid_feature, repid);
149
150 /* device initialize */
151 (void)uoak_led_ctrl(scc, OAK_TARGET_RAM, OAK_LED_ON0x1);
152 err = uoak_set_sample_rate(scc, OAK_TARGET_RAM, UOAKV_SAMPLE_RATE100);
153 if (err) {
154 printf("%s: could not set sampling rate. exit\n",
155 sc->sc_hdev.sc_dev.dv_xname);
156 return;
157 }
158
159 /* query and print device setting */
160 uoak_get_devinfo(scc);
161 uoak_print_devinfo(scc);
162
163 DPRINTF((" config in RAM\n"));
164 uoak_get_setting(scc, OAK_TARGET_RAM);
165 uoak_print_setting(scc, OAK_TARGET_RAM);
166#ifdef UOAKV_DEBUG
167 DPRINTF((" config in FRASH\n"));
168 uoak_get_setting(scc, OAK_TARGET_FLASH);
169 uoak_print_setting(scc, OAK_TARGET_FLASH);
170#endif
171
172 /* attach sensor */
173 strlcpy(sc->sc_sensordev.xname, sc->sc_hdev.sc_dev.dv_xname,
174 sizeof(sc->sc_sensordev.xname));
175 for (i = 0; i < OAK_V_MAXSENSORS8; i++)
176 uoak_sensor_attach(scc, &sc->sc_sensor[i].v, SENSOR_VOLTS_DC);
177
178 /* start sensor */
179 sc->sc_sensortask = sensor_task_register(sc, uoakv_refresh,
180 UOAKV_REFRESH_PERIOD1);
181 if (sc->sc_sensortask == NULL((void *)0)) {
182 printf(", unable to register update task\n");
183 return;
184 }
185 sensordev_install(&sc->sc_sensordev);
186
187 err = uhidev_open(&sc->sc_hdev);
188 if (err) {
189 printf("%s: could not open interrupt pipe, quit\n",
190 sc->sc_hdev.sc_dev.dv_xname);
191 return;
192 }
193 scc->sc_ibuf = malloc(scc->sc_ilen, M_USBDEV102, M_WAITOK0x0001);
194
195 DPRINTF(("uoakv_attach: complete\n"));
196}
197
198int
199uoakv_detach(struct device *self, int flags)
200{
201 struct uoakv_softc *sc = (struct uoakv_softc *)self;
202 struct uoak_softc *scc = &sc->sc_uoak_softc;
203 int i, rv = 0;
204
205 wakeup(&sc->sc_sensortask);
206 sensordev_deinstall(&sc->sc_sensordev);
207
208 for (i = 0; i < OAK_V_MAXSENSORS8; i++)
209 uoak_sensor_detach(scc, &sc->sc_sensor[i].v);
210
211 if (sc->sc_sensortask != NULL((void *)0))
212 sensor_task_unregister(sc->sc_sensortask);
213
214 if (sc->sc_hdev.sc_state & UHIDEV_OPEN0x01)
215 uhidev_close(&sc->sc_hdev);
216
217 if (scc->sc_ibuf != NULL((void *)0)) {
218 free(scc->sc_ibuf, M_USBDEV102, scc->sc_ilen);
219 scc->sc_ibuf = NULL((void *)0);
220 }
221
222 return (rv);
223}
224
225void
226uoakv_intr(struct uhidev *addr, void *ibuf, u_int len)
227{
228 struct uoakv_softc *sc = (struct uoakv_softc *)addr;
229 struct uoak_softc *scc = &sc->sc_uoak_softc;
230 int i, idx, frame;
231 int16_t val;
232
233 if (scc->sc_ibuf == NULL((void *)0))
234 return;
235
236 memcpy(scc->sc_ibuf, ibuf, len)__builtin_memcpy((scc->sc_ibuf), (ibuf), (len));
237 frame = (scc->sc_ibuf[1] << 8) + scc->sc_ibuf[0];
Value stored to 'frame' is never read
238
239 for (i = 0; i < OAK_V_MAXSENSORS8; i++) {
240 idx = (i + 1) * 2;
241 val = (int16_t)((scc->sc_ibuf[idx+1] << 8) | scc->sc_ibuf[idx]);
242 uoak_sensor_update(&sc->sc_sensor[i].v, val);
243 }
244}
245
246void
247uoakv_refresh(void *arg)
248{
249 struct uoakv_softc *sc = arg;
250 struct uoak_softc *scc = &sc->sc_uoak_softc;
251 uint8_t led;
252 int i;
253
254 /* blink LED for each cycle */
255 if (uoak_led_status(scc, OAK_TARGET_RAM, &led) < 0)
256 DPRINTF(("status query error\n"));
257 if (led == OAK_LED_OFF0x0)
258 (void)uoak_led_ctrl(scc, OAK_TARGET_RAM, OAK_LED_ON0x1);
259 else
260 (void)uoak_led_ctrl(scc, OAK_TARGET_RAM, OAK_LED_OFF0x0);
261
262 for (i = 0; i < OAK_V_MAXSENSORS8; i++)
263 uoak_sensor_refresh(&sc->sc_sensor[i].v, 1000, 0);
264}
265
266int
267uoakv_get_channel_setting(struct uoakv_softc *sc, enum uoak_target target,
268 int ch)
269{
270 struct uoak_softc *scc = &sc->sc_uoak_softc;
271 uint16_t cmd, result;
272
273 memset(&scc->sc_rcmd, 0, sizeof(struct uoak_rcmd))__builtin_memset((&scc->sc_rcmd), (0), (sizeof(struct uoak_rcmd
)))
;
274 scc->sc_rcmd.target = target;
275 scc->sc_rcmd.datasize = 0x2;
276
277#define OAK_V_CHANNEL_IDX_OFFSET3 3
278 cmd = (ch + OAK_V_CHANNEL_IDX_OFFSET3);
279 USETW(&scc->sc_rcmd.cmd, cmd)(*(u_int16_t *)(&scc->sc_rcmd.cmd) = (cmd));
280
281 if (uoak_get_cmd(scc) < 0)
282 return EIO5;
283
284 result = (scc->sc_buf[2] << 8) + scc->sc_buf[1];
285 sc->sc_sensor[ch].offset[target] = result;
286
287 return 0;
288}
289
290int
291uoakv_get_sensor_setting(struct uoakv_softc *sc, enum uoak_target target)
292{
293 struct uoak_softc *scc = &sc->sc_uoak_softc;
294 uint8_t result;
295
296 memset(&scc->sc_rcmd, 0, sizeof(struct uoak_rcmd))__builtin_memset((&scc->sc_rcmd), (0), (sizeof(struct uoak_rcmd
)))
;
297 scc->sc_rcmd.target = target;
298 scc->sc_rcmd.datasize = 0x1;
299 USETW(&scc->sc_rcmd.cmd, OAK_CMD_SENSORSETTING)(*(u_int16_t *)(&scc->sc_rcmd.cmd) = (0x0002));
300
301 if (uoak_get_cmd(scc) < 0)
302 return EIO5;
303
304 result = scc->sc_buf[1];
305 sc->sc_inputmode[target] = (result & OAK_V_SENSOR_INPUTMODEMASK(0x1 << 0));
306
307 return 0;
308}
309
310/* device specific functions */
311void
312uoakv_dev_setting(void *parent, enum uoak_target target)
313{
314 struct uoakv_softc *sc = (struct uoakv_softc *)parent;
315 int i;
316
317 /* get device specific configuration */
318 (void)uoakv_get_sensor_setting(sc, target);
319 for (i = 0; i < OAK_V_MAXSENSORS8; i++)
320 (void)uoakv_get_channel_setting(sc, target, i);
321}
322
323void
324uoakv_dev_print(void *parent, enum uoak_target target)
325{
326 struct uoakv_softc *sc = (struct uoakv_softc *)parent;
327 int i;
328
329 printf(", %s", (sc->sc_inputmode[target] ?
330 "Pseudo-Differential" : "Single-Ended"));
331
332 printf(", ADC channel offsets:\n");
333 printf("%s: ", sc->sc_hdev.sc_dev.dv_xname);
334 for (i = 0; i < OAK_V_MAXSENSORS8; i++)
335 printf("ch%02d %2d.%02d, ", i,
336 sc->sc_sensor[i].offset[target] / 100,
337 sc->sc_sensor[i].offset[target] % 100);
338}