Bug Summary

File:dev/usb/usb.c
Warning:line 659, column 19
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 usb.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/usb.c
1/* $OpenBSD: usb.c,v 1.129 2022/01/09 05:43:02 jsg Exp $ */
2/* $NetBSD: usb.c,v 1.77 2003/01/01 00:10:26 thorpej Exp $ */
3
4/*
5 * Copyright (c) 1998, 2002 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Lennart Augustsson (lennart@augustsson.net) at
10 * Carlstedt Research & Technology.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33
34/*
35 * USB specifications and other documentation can be found at
36 * https://www.usb.org/documents
37 */
38
39#include "ohci.h"
40#include "uhci.h"
41#include "ehci.h"
42
43#include <sys/param.h>
44#include <sys/systm.h>
45#include <sys/kernel.h>
46#include <sys/malloc.h>
47#include <sys/device.h>
48#include <sys/timeout.h>
49#include <sys/kthread.h>
50#include <sys/conf.h>
51#include <sys/fcntl.h>
52#include <sys/poll.h>
53#include <sys/selinfo.h>
54#include <sys/signalvar.h>
55#include <sys/time.h>
56#include <sys/rwlock.h>
57
58#include <dev/usb/usb.h>
59#include <dev/usb/usbdi.h>
60#include <dev/usb/usbdi_util.h>
61
62#include <machine/bus.h>
63
64#include <dev/usb/usbdivar.h>
65#include <dev/usb/usb_mem.h>
66#include <dev/usb/usbpcap.h>
67
68#ifdef USB_DEBUG
69#define DPRINTF(x) do { if (usbdebug) printf x; } while (0)
70#define DPRINTFN(n,x) do { if (usbdebug>(n)) printf x; } while (0)
71int usbdebug = 0;
72#if defined(UHCI_DEBUG) && NUHCI1 > 0
73extern int uhcidebug;
74#endif
75#if defined(OHCI_DEBUG) && NOHCI1 > 0
76extern int ohcidebug;
77#endif
78#if defined(EHCI_DEBUG) && NEHCI1 > 0
79extern int ehcidebug;
80#endif
81/*
82 * 0 - do usual exploration
83 * !0 - do no exploration
84 */
85int usb_noexplore = 0;
86#else
87#define DPRINTF(x)
88#define DPRINTFN(n,x)
89#endif
90
91struct usb_softc {
92 struct device sc_dev; /* base device */
93 struct usbd_bus *sc_bus; /* USB controller */
94 struct usbd_port sc_port; /* dummy port for root hub */
95 int sc_speed;
96
97 struct usb_task sc_explore_task;
98
99 struct timeval sc_ptime;
100};
101
102struct rwlock usbpalock;
103
104TAILQ_HEAD(, usb_task)struct { struct usb_task *tqh_first; struct usb_task **tqh_last
; }
usb_abort_tasks;
105TAILQ_HEAD(, usb_task)struct { struct usb_task *tqh_first; struct usb_task **tqh_last
; }
usb_explore_tasks;
106TAILQ_HEAD(, usb_task)struct { struct usb_task *tqh_first; struct usb_task **tqh_last
; }
usb_generic_tasks;
107
108static int usb_nbuses = 0;
109static int usb_run_tasks, usb_run_abort_tasks;
110int explore_pending;
111const char *usbrev_str[] = USBREV_STR{ "unknown", "pre 1.0", "1.0", "1.1", "2.0", "3.0" };
112
113void usb_explore(void *);
114void usb_create_task_threads(void *);
115void usb_task_thread(void *);
116struct proc *usb_task_thread_proc = NULL((void *)0);
117void usb_abort_task_thread(void *);
118struct proc *usb_abort_task_thread_proc = NULL((void *)0);
119
120void usb_fill_udc_task(void *);
121void usb_fill_udf_task(void *);
122
123int usb_match(struct device *, void *, void *);
124void usb_attach(struct device *, struct device *, void *);
125int usb_detach(struct device *, int);
126int usb_activate(struct device *, int);
127
128int usb_attach_roothub(struct usb_softc *);
129void usb_detach_roothub(struct usb_softc *);
130
131struct cfdriver usb_cd = {
132 NULL((void *)0), "usb", DV_DULL
133};
134
135const struct cfattach usb_ca = {
136 sizeof(struct usb_softc), usb_match, usb_attach, usb_detach,
137 usb_activate,
138};
139
140int
141usb_match(struct device *parent, void *match, void *aux)
142{
143 return (1);
144}
145
146void
147usb_attach(struct device *parent, struct device *self, void *aux)
148{
149 struct usb_softc *sc = (struct usb_softc *)self;
150 int usbrev;
151
152 if (usb_nbuses == 0) {
153 rw_init(&usbpalock, "usbpalock")_rw_init_flags(&usbpalock, "usbpalock", 0, ((void *)0));
154 TAILQ_INIT(&usb_abort_tasks)do { (&usb_abort_tasks)->tqh_first = ((void *)0); (&
usb_abort_tasks)->tqh_last = &(&usb_abort_tasks)->
tqh_first; } while (0)
;
155 TAILQ_INIT(&usb_explore_tasks)do { (&usb_explore_tasks)->tqh_first = ((void *)0); (&
usb_explore_tasks)->tqh_last = &(&usb_explore_tasks
)->tqh_first; } while (0)
;
156 TAILQ_INIT(&usb_generic_tasks)do { (&usb_generic_tasks)->tqh_first = ((void *)0); (&
usb_generic_tasks)->tqh_last = &(&usb_generic_tasks
)->tqh_first; } while (0)
;
157 usb_run_tasks = usb_run_abort_tasks = 1;
158 kthread_create_deferred(usb_create_task_threads, NULL((void *)0));
159 }
160 usb_nbuses++;
161
162 sc->sc_bus = aux;
163 sc->sc_bus->usbctl = self;
164 sc->sc_port.power = USB_MAX_POWER500;
165
166 usbrev = sc->sc_bus->usbrev;
167 printf(": USB revision %s", usbrev_str[usbrev]);
168 switch (usbrev) {
169 case USBREV_1_02:
170 case USBREV_1_13:
171 sc->sc_speed = USB_SPEED_FULL2;
172 break;
173 case USBREV_2_04:
174 sc->sc_speed = USB_SPEED_HIGH3;
175 break;
176 case USBREV_3_05:
177 sc->sc_speed = USB_SPEED_SUPER4;
178 break;
179 default:
180 printf(", not supported\n");
181 sc->sc_bus->dying = 1;
182 return;
183 }
184 printf("\n");
185
186#if NBPFILTER1 > 0
187 sc->sc_bus->bpfif = bpfsattach(&sc->sc_bus->bpf, sc->sc_dev.dv_xname,
188 DLT_USBPCAP249, sizeof(struct usbpcap_pkt_hdr));
189#endif
190
191 /* Make sure not to use tsleep() if we are cold booting. */
192 if (cold)
193 sc->sc_bus->use_polling++;
194
195 /* Don't let hub interrupts cause explore until ready. */
196 sc->sc_bus->flags |= USB_BUS_CONFIG_PENDING0x01;
197
198 /* explore task */
199 usb_init_task(&sc->sc_explore_task, usb_explore, sc,((&sc->sc_explore_task)->fun = (usb_explore), (&
sc->sc_explore_task)->arg = (sc), (&sc->sc_explore_task
)->type = (1), (&sc->sc_explore_task)->state = 0x0
)
200 USB_TASK_TYPE_EXPLORE)((&sc->sc_explore_task)->fun = (usb_explore), (&
sc->sc_explore_task)->arg = (sc), (&sc->sc_explore_task
)->type = (1), (&sc->sc_explore_task)->state = 0x0
)
;
201
202 sc->sc_bus->soft = softintr_establish(IPL_SOFTUSB0x5,
203 sc->sc_bus->methods->soft_intr, sc->sc_bus);
204 if (sc->sc_bus->soft == NULL((void *)0)) {
205 printf("%s: can't register softintr\n", sc->sc_dev.dv_xname);
206 sc->sc_bus->dying = 1;
207 return;
208 }
209
210 if (!usb_attach_roothub(sc)) {
211 struct usbd_device *dev = sc->sc_bus->root_hub;
212#if 1
213 /*
214 * Turning this code off will delay attachment of USB devices
215 * until the USB task thread is running, which means that
216 * the keyboard will not work until after cold boot.
217 */
218 if (cold && (sc->sc_dev.dv_cfdata->cf_flags & 1))
219 dev->hub->explore(sc->sc_bus->root_hub);
220#endif
221 }
222
223 if (cold)
224 sc->sc_bus->use_polling--;
225
226 if (!sc->sc_bus->dying) {
227 getmicrouptime(&sc->sc_ptime);
228 if (sc->sc_bus->usbrev == USBREV_2_04)
229 explore_pending++;
230 config_pending_incr();
231 usb_needs_explore(sc->sc_bus->root_hub, 1);
232 }
233}
234
235int
236usb_attach_roothub(struct usb_softc *sc)
237{
238 struct usbd_device *dev;
239
240 if (usbd_new_device(&sc->sc_dev, sc->sc_bus, 0, sc->sc_speed, 0,
241 &sc->sc_port)) {
242 printf("%s: root hub problem\n", sc->sc_dev.dv_xname);
243 sc->sc_bus->dying = 1;
244 return (1);
245 }
246
247 dev = sc->sc_port.device;
248 if (dev->hub == NULL((void *)0)) {
249 printf("%s: root device is not a hub\n", sc->sc_dev.dv_xname);
250 sc->sc_bus->dying = 1;
251 return (1);
252 }
253 sc->sc_bus->root_hub = dev;
254
255 return (0);
256}
257
258void
259usb_detach_roothub(struct usb_softc *sc)
260{
261 /*
262 * To avoid races with the usb task thread, mark the root hub
263 * as disconnecting and schedule an exploration task to detach
264 * it.
265 */
266 sc->sc_bus->flags |= USB_BUS_DISCONNECTING0x02;
267 /*
268 * Reset the dying flag in case it has been set by the interrupt
269 * handler when unplugging an HC card otherwise the task wont be
270 * scheduled. This is safe since a dead HC should not trigger
271 * new interrupt.
272 */
273 sc->sc_bus->dying = 0;
274 usb_needs_explore(sc->sc_bus->root_hub, 0);
275
276 usb_wait_task(sc->sc_bus->root_hub, &sc->sc_explore_task);
277
278 sc->sc_bus->root_hub = NULL((void *)0);
279}
280
281void
282usb_create_task_threads(void *arg)
283{
284 if (kthread_create(usb_abort_task_thread, NULL((void *)0),
285 &usb_abort_task_thread_proc, "usbatsk"))
286 panic("unable to create usb abort task thread");
287
288 if (kthread_create(usb_task_thread, NULL((void *)0),
289 &usb_task_thread_proc, "usbtask"))
290 panic("unable to create usb task thread");
291}
292
293/*
294 * Add a task to be performed by the task thread. This function can be
295 * called from any context and the task will be executed in a process
296 * context ASAP.
297 */
298void
299usb_add_task(struct usbd_device *dev, struct usb_task *task)
300{
301 int s;
302
303 /*
304 * If the thread detaching ``dev'' is sleeping, waiting
305 * for all submitted transfers to finish, we must be able
306 * to enqueue abort tasks. Otherwise timeouts can't give
307 * back submitted transfers to the stack.
308 */
309 if (usbd_is_dying(dev) && (task->type != USB_TASK_TYPE_ABORT2))
310 return;
311
312 DPRINTFN(2,("%s: task=%p state=%d type=%d\n", __func__, task,
313 task->state, task->type));
314
315 s = splusb()splraise(0x5);
316 if (!(task->state & USB_TASK_STATE_ONQ0x1)) {
317 switch (task->type) {
318 case USB_TASK_TYPE_ABORT2:
319 TAILQ_INSERT_TAIL(&usb_abort_tasks, task, next)do { (task)->next.tqe_next = ((void *)0); (task)->next.
tqe_prev = (&usb_abort_tasks)->tqh_last; *(&usb_abort_tasks
)->tqh_last = (task); (&usb_abort_tasks)->tqh_last =
&(task)->next.tqe_next; } while (0)
;
320 break;
321 case USB_TASK_TYPE_EXPLORE1:
322 TAILQ_INSERT_TAIL(&usb_explore_tasks, task, next)do { (task)->next.tqe_next = ((void *)0); (task)->next.
tqe_prev = (&usb_explore_tasks)->tqh_last; *(&usb_explore_tasks
)->tqh_last = (task); (&usb_explore_tasks)->tqh_last
= &(task)->next.tqe_next; } while (0)
;
323 break;
324 case USB_TASK_TYPE_GENERIC0:
325 TAILQ_INSERT_TAIL(&usb_generic_tasks, task, next)do { (task)->next.tqe_next = ((void *)0); (task)->next.
tqe_prev = (&usb_generic_tasks)->tqh_last; *(&usb_generic_tasks
)->tqh_last = (task); (&usb_generic_tasks)->tqh_last
= &(task)->next.tqe_next; } while (0)
;
326 break;
327 }
328 task->state |= USB_TASK_STATE_ONQ0x1;
329 task->dev = dev;
330 }
331 if (task->type == USB_TASK_TYPE_ABORT2)
332 wakeup(&usb_run_abort_tasks);
333 else
334 wakeup(&usb_run_tasks);
335 splx(s)spllower(s);
336}
337
338void
339usb_rem_task(struct usbd_device *dev, struct usb_task *task)
340{
341 int s;
342
343 if (!(task->state & USB_TASK_STATE_ONQ0x1))
344 return;
345
346 DPRINTFN(2,("%s: task=%p state=%d type=%d\n", __func__, task,
347 task->state, task->type));
348
349 s = splusb()splraise(0x5);
350
351 switch (task->type) {
352 case USB_TASK_TYPE_ABORT2:
353 TAILQ_REMOVE(&usb_abort_tasks, task, next)do { if (((task)->next.tqe_next) != ((void *)0)) (task)->
next.tqe_next->next.tqe_prev = (task)->next.tqe_prev; else
(&usb_abort_tasks)->tqh_last = (task)->next.tqe_prev
; *(task)->next.tqe_prev = (task)->next.tqe_next; ((task
)->next.tqe_prev) = ((void *)-1); ((task)->next.tqe_next
) = ((void *)-1); } while (0)
;
354 break;
355 case USB_TASK_TYPE_EXPLORE1:
356 TAILQ_REMOVE(&usb_explore_tasks, task, next)do { if (((task)->next.tqe_next) != ((void *)0)) (task)->
next.tqe_next->next.tqe_prev = (task)->next.tqe_prev; else
(&usb_explore_tasks)->tqh_last = (task)->next.tqe_prev
; *(task)->next.tqe_prev = (task)->next.tqe_next; ((task
)->next.tqe_prev) = ((void *)-1); ((task)->next.tqe_next
) = ((void *)-1); } while (0)
;
357 break;
358 case USB_TASK_TYPE_GENERIC0:
359 TAILQ_REMOVE(&usb_generic_tasks, task, next)do { if (((task)->next.tqe_next) != ((void *)0)) (task)->
next.tqe_next->next.tqe_prev = (task)->next.tqe_prev; else
(&usb_generic_tasks)->tqh_last = (task)->next.tqe_prev
; *(task)->next.tqe_prev = (task)->next.tqe_next; ((task
)->next.tqe_prev) = ((void *)-1); ((task)->next.tqe_next
) = ((void *)-1); } while (0)
;
360 break;
361 }
362 task->state &= ~USB_TASK_STATE_ONQ0x1;
363 if (task->state == USB_TASK_STATE_NONE0x0)
364 wakeup(task);
365
366 splx(s)spllower(s);
367}
368
369void
370usb_wait_task(struct usbd_device *dev, struct usb_task *task)
371{
372 int s;
373
374 DPRINTFN(2,("%s: task=%p state=%d type=%d\n", __func__, task,
375 task->state, task->type));
376
377 if (task->state == USB_TASK_STATE_NONE0x0)
378 return;
379
380 s = splusb()splraise(0x5);
381 while (task->state != USB_TASK_STATE_NONE0x0) {
382 DPRINTF(("%s: waiting for task to complete\n", __func__));
383 tsleep_nsec(task, PWAIT32, "endtask", INFSLP0xffffffffffffffffULL);
384 }
385 splx(s)spllower(s);
386}
387
388void
389usb_rem_wait_task(struct usbd_device *dev, struct usb_task *task)
390{
391 usb_rem_task(dev, task);
392 usb_wait_task(dev, task);
393}
394
395void
396usb_task_thread(void *arg)
397{
398 struct usb_task *task;
399 int s;
400
401 DPRINTF(("usb_task_thread: start\n"));
402
403 s = splusb()splraise(0x5);
404 while (usb_run_tasks) {
405 if ((task = TAILQ_FIRST(&usb_explore_tasks)((&usb_explore_tasks)->tqh_first)) != NULL((void *)0))
406 TAILQ_REMOVE(&usb_explore_tasks, task, next)do { if (((task)->next.tqe_next) != ((void *)0)) (task)->
next.tqe_next->next.tqe_prev = (task)->next.tqe_prev; else
(&usb_explore_tasks)->tqh_last = (task)->next.tqe_prev
; *(task)->next.tqe_prev = (task)->next.tqe_next; ((task
)->next.tqe_prev) = ((void *)-1); ((task)->next.tqe_next
) = ((void *)-1); } while (0)
;
407 else if ((task = TAILQ_FIRST(&usb_generic_tasks)((&usb_generic_tasks)->tqh_first)) != NULL((void *)0))
408 TAILQ_REMOVE(&usb_generic_tasks, task, next)do { if (((task)->next.tqe_next) != ((void *)0)) (task)->
next.tqe_next->next.tqe_prev = (task)->next.tqe_prev; else
(&usb_generic_tasks)->tqh_last = (task)->next.tqe_prev
; *(task)->next.tqe_prev = (task)->next.tqe_next; ((task
)->next.tqe_prev) = ((void *)-1); ((task)->next.tqe_next
) = ((void *)-1); } while (0)
;
409 else {
410 tsleep_nsec(&usb_run_tasks, PWAIT32, "usbtsk", INFSLP0xffffffffffffffffULL);
411 continue;
412 }
413 /*
414 * Set the state run bit before clearing the onq bit.
415 * This avoids state == none between dequeue and
416 * execution, which could cause usb_wait_task() to do
417 * the wrong thing.
418 */
419 task->state |= USB_TASK_STATE_RUN0x2;
420 task->state &= ~USB_TASK_STATE_ONQ0x1;
421 /* Don't actually execute the task if dying. */
422 if (!usbd_is_dying(task->dev)) {
423 splx(s)spllower(s);
424 task->fun(task->arg);
425 s = splusb()splraise(0x5);
426 }
427 task->state &= ~USB_TASK_STATE_RUN0x2;
428 if (task->state == USB_TASK_STATE_NONE0x0)
429 wakeup(task);
430 }
431 splx(s)spllower(s);
432
433 kthread_exit(0);
434}
435
436/*
437 * This thread is ONLY for the HCI drivers to be able to abort xfers.
438 * Synchronous xfers sleep the task thread, so the aborts need to happen
439 * in a different thread.
440 */
441void
442usb_abort_task_thread(void *arg)
443{
444 struct usb_task *task;
445 int s;
446
447 DPRINTF(("usb_xfer_abort_thread: start\n"));
448
449 s = splusb()splraise(0x5);
450 while (usb_run_abort_tasks) {
451 if ((task = TAILQ_FIRST(&usb_abort_tasks)((&usb_abort_tasks)->tqh_first)) != NULL((void *)0))
452 TAILQ_REMOVE(&usb_abort_tasks, task, next)do { if (((task)->next.tqe_next) != ((void *)0)) (task)->
next.tqe_next->next.tqe_prev = (task)->next.tqe_prev; else
(&usb_abort_tasks)->tqh_last = (task)->next.tqe_prev
; *(task)->next.tqe_prev = (task)->next.tqe_next; ((task
)->next.tqe_prev) = ((void *)-1); ((task)->next.tqe_next
) = ((void *)-1); } while (0)
;
453 else {
454 tsleep_nsec(&usb_run_abort_tasks, PWAIT32, "usbatsk",
455 INFSLP0xffffffffffffffffULL);
456 continue;
457 }
458 /*
459 * Set the state run bit before clearing the onq bit.
460 * This avoids state == none between dequeue and
461 * execution, which could cause usb_wait_task() to do
462 * the wrong thing.
463 */
464 task->state |= USB_TASK_STATE_RUN0x2;
465 task->state &= ~USB_TASK_STATE_ONQ0x1;
466 splx(s)spllower(s);
467 task->fun(task->arg);
468 s = splusb()splraise(0x5);
469 task->state &= ~USB_TASK_STATE_RUN0x2;
470 if (task->state == USB_TASK_STATE_NONE0x0)
471 wakeup(task);
472 }
473 splx(s)spllower(s);
474
475 kthread_exit(0);
476}
477
478int
479usbctlprint(void *aux, const char *pnp)
480{
481 /* only "usb"es can attach to host controllers */
482 if (pnp)
483 printf("usb at %s", pnp);
484
485 return (UNCONF1);
486}
487
488int
489usbopen(dev_t dev, int flag, int mode, struct proc *p)
490{
491 int unit = minor(dev)((unsigned)((dev) & 0xff) | (((dev) & 0xffff0000) >>
8))
;
492 struct usb_softc *sc;
493
494 if (unit >= usb_cd.cd_ndevs)
495 return (ENXIO6);
496 sc = usb_cd.cd_devs[unit];
497 if (sc == NULL((void *)0))
498 return (ENXIO6);
499
500 if (sc->sc_bus->dying)
501 return (EIO5);
502
503 return (0);
504}
505
506int
507usbclose(dev_t dev, int flag, int mode, struct proc *p)
508{
509 return (0);
510}
511
512void
513usb_fill_udc_task(void *arg)
514{
515 struct usb_device_cdesc *udc = (struct usb_device_cdesc *)arg;
516 struct usb_softc *sc;
517 struct usbd_device *dev;
518 int addr = udc->udc_addr, cdesc_len;
519 usb_config_descriptor_t *cdesc;
520
521 /* check that the bus and device are still present */
522 if (udc->udc_bus >= usb_cd.cd_ndevs)
523 return;
524 sc = usb_cd.cd_devs[udc->udc_bus];
525 if (sc == NULL((void *)0))
526 return;
527 dev = sc->sc_bus->devices[udc->udc_addr];
528 if (dev == NULL((void *)0))
529 return;
530
531 cdesc = usbd_get_cdesc(sc->sc_bus->devices[addr],
532 udc->udc_config_index, &cdesc_len);
533 if (cdesc == NULL((void *)0))
534 return;
535 udc->udc_desc = *cdesc;
536 free(cdesc, M_TEMP127, cdesc_len);
537}
538
539void
540usb_fill_udf_task(void *arg)
541{
542 struct usb_device_fdesc *udf = (struct usb_device_fdesc *)arg;
543 struct usb_softc *sc;
544 struct usbd_device *dev;
545 int addr = udf->udf_addr;
546 usb_config_descriptor_t *cdesc;
547
548 /* check that the bus and device are still present */
549 if (udf->udf_bus >= usb_cd.cd_ndevs)
550 return;
551 sc = usb_cd.cd_devs[udf->udf_bus];
552 if (sc == NULL((void *)0))
553 return;
554 dev = sc->sc_bus->devices[udf->udf_addr];
555 if (dev == NULL((void *)0))
556 return;
557
558 cdesc = usbd_get_cdesc(sc->sc_bus->devices[addr],
559 udf->udf_config_index, &udf->udf_size);
560 udf->udf_data = (char *)cdesc;
561}
562
563int
564usbioctl(dev_t devt, u_long cmd, caddr_t data, int flag, struct proc *p)
565{
566 struct usb_softc *sc;
567 int unit = minor(devt)((unsigned)((devt) & 0xff) | (((devt) & 0xffff0000) >>
8))
;
568 int error;
569
570 sc = usb_cd.cd_devs[unit];
571
572 if (sc->sc_bus->dying)
1
Assuming field 'dying' is 0
2
Taking false branch
573 return (EIO5);
574
575 error = 0;
576 switch (cmd) {
3
Control jumps to 'case 3223344385:' at line 596
577#ifdef USB_DEBUG
578 case USB_SETDEBUG((unsigned long)0x80000000 | ((sizeof(unsigned int) & 0x1fff
) << 16) | ((('U')) << 8) | ((2)))
:
579 /* only root can access to these debug flags */
580 if ((error = suser(curproc({struct cpu_info *__ci; asm volatile("movq %%gs:%P1,%0" : "=r"
(__ci) :"n" (__builtin_offsetof(struct cpu_info, ci_self)));
__ci;})->ci_curproc
)) != 0)
581 return (error);
582 if (!(flag & FWRITE0x0002))
583 return (EBADF9);
584 usbdebug = ((*(unsigned int *)data) & 0x000000ff);
585#if defined(UHCI_DEBUG) && NUHCI1 > 0
586 uhcidebug = ((*(unsigned int *)data) & 0x0000ff00) >> 8;
587#endif
588#if defined(OHCI_DEBUG) && NOHCI1 > 0
589 ohcidebug = ((*(unsigned int *)data) & 0x00ff0000) >> 16;
590#endif
591#if defined(EHCI_DEBUG) && NEHCI1 > 0
592 ehcidebug = ((*(unsigned int *)data) & 0xff000000) >> 24;
593#endif
594 break;
595#endif /* USB_DEBUG */
596 case USB_REQUEST(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct usb_ctl_request) & 0x1fff) << 16) | ((('U')
) << 8) | ((1)))
:
597 {
598 struct usb_ctl_request *ur = (void *)data;
599 size_t len = UGETW(ur->ucr_request.wLength)(*(u_int16_t *)(ur->ucr_request.wLength)), mlen;
600 struct iovec iov;
601 struct uio uio;
602 void *ptr = NULL((void *)0);
603 int addr = ur->ucr_addr;
604 usbd_status err;
605
606 if (!(flag & FWRITE0x0002))
4
Assuming the condition is false
5
Taking false branch
607 return (EBADF9);
608
609 DPRINTF(("%s: USB_REQUEST addr=%d len=%zu\n", __func__, addr, len));
610 /* Avoid requests that would damage the bus integrity. */
611 if ((ur->ucr_request.bmRequestType == UT_WRITE_DEVICE(0x00 | 0x00 | 0x00) &&
6
Assuming the condition is false
612 ur->ucr_request.bRequest == UR_SET_ADDRESS0x05) ||
613 (ur->ucr_request.bmRequestType == UT_WRITE_DEVICE(0x00 | 0x00 | 0x00) &&
614 ur->ucr_request.bRequest == UR_SET_CONFIG0x09) ||
615 (ur->ucr_request.bmRequestType == UT_WRITE_INTERFACE(0x00 | 0x00 | 0x01) &&
7
Assuming the condition is false
616 ur->ucr_request.bRequest == UR_SET_INTERFACE0x0b))
617 return (EINVAL22);
618
619 if (len > 32767)
8
Assuming 'len' is <= 32767
9
Taking false branch
620 return (EINVAL22);
621 if (addr < 0 || addr >= USB_MAX_DEVICES128)
10
Assuming 'addr' is >= 0
11
Assuming 'addr' is < USB_MAX_DEVICES
12
Taking false branch
622 return (EINVAL22);
623 if (sc->sc_bus->devices[addr] == NULL((void *)0))
13
Assuming the condition is false
14
Taking false branch
624 return (ENXIO6);
625 if (len != 0) {
15
Assuming 'len' is equal to 0
16
Taking false branch
626 iov.iov_base = (caddr_t)ur->ucr_data;
627 iov.iov_len = len;
628 uio.uio_iov = &iov;
629 uio.uio_iovcnt = 1;
630 uio.uio_resid = len;
631 uio.uio_offset = 0;
632 uio.uio_segflg = UIO_USERSPACE;
633 uio.uio_rw =
634 ur->ucr_request.bmRequestType & UT_READ0x80 ?
635 UIO_READ : UIO_WRITE;
636 uio.uio_procp = p;
637 if ((ptr = malloc(len, M_TEMP127, M_NOWAIT0x0002)) == NULL((void *)0)) {
638 error = ENOMEM12;
639 goto ret;
640 }
641 if (uio.uio_rw == UIO_WRITE) {
642 error = uiomove(ptr, len, &uio);
643 if (error)
644 goto ret;
645 }
646 }
647 err = usbd_do_request_flags(sc->sc_bus->devices[addr],
648 &ur->ucr_request, ptr, ur->ucr_flags,
649 &ur->ucr_actlen, USBD_DEFAULT_TIMEOUT5000);
650 if (err) {
17
Assuming 'err' is 0
18
Taking false branch
651 error = EIO5;
652 goto ret;
653 }
654 /* Only if USBD_SHORT_XFER_OK is set. */
655 mlen = len;
656 if (mlen > ur->ucr_actlen)
19
Assuming 'mlen' is > field 'ucr_actlen'
20
Taking true branch
657 mlen = ur->ucr_actlen;
658 if (mlen
20.1
'mlen' is not equal to 0
!= 0) {
21
Taking true branch
659 if (uio.uio_rw == UIO_READ) {
22
The left operand of '==' is a garbage value
660 error = uiomove(ptr, mlen, &uio);
661 if (error)
662 goto ret;
663 }
664 }
665 ret:
666 free(ptr, M_TEMP127, len);
667 return (error);
668 }
669
670 case USB_DEVICEINFO(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct usb_device_info) & 0x1fff) << 16) | ((('U')
) << 8) | ((4)))
:
671 {
672 struct usb_device_info *di = (void *)data;
673 int addr = di->udi_addr;
674 struct usbd_device *dev;
675
676 if (addr < 1 || addr >= USB_MAX_DEVICES128)
677 return (EINVAL22);
678
679 dev = sc->sc_bus->devices[addr];
680 if (dev == NULL((void *)0))
681 return (ENXIO6);
682
683 usbd_fill_deviceinfo(dev, di);
684 break;
685 }
686
687 case USB_DEVICESTATS((unsigned long)0x40000000 | ((sizeof(struct usb_device_stats
) & 0x1fff) << 16) | ((('U')) << 8) | ((5)))
:
688 *(struct usb_device_stats *)data = sc->sc_bus->stats;
689 break;
690
691 case USB_DEVICE_GET_DDESC(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct usb_device_ddesc) & 0x1fff) << 16) | ((('U'
)) << 8) | ((8)))
:
692 {
693 struct usb_device_ddesc *udd = (struct usb_device_ddesc *)data;
694 int addr = udd->udd_addr;
695 struct usbd_device *dev;
696
697 if (addr < 1 || addr >= USB_MAX_DEVICES128)
698 return (EINVAL22);
699
700 dev = sc->sc_bus->devices[addr];
701 if (dev == NULL((void *)0))
702 return (ENXIO6);
703
704 udd->udd_bus = unit;
705
706 udd->udd_desc = *usbd_get_device_descriptor(dev);
707 break;
708 }
709
710 case USB_DEVICE_GET_CDESC(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct usb_device_cdesc) & 0x1fff) << 16) | ((('U'
)) << 8) | ((6)))
:
711 {
712 struct usb_device_cdesc *udc = (struct usb_device_cdesc *)data;
713 int addr = udc->udc_addr;
714 struct usb_task udc_task;
715
716 if (addr < 1 || addr >= USB_MAX_DEVICES128)
717 return (EINVAL22);
718 if (sc->sc_bus->devices[addr] == NULL((void *)0))
719 return (ENXIO6);
720
721 udc->udc_bus = unit;
722
723 udc->udc_desc.bLength = 0;
724 usb_init_task(&udc_task, usb_fill_udc_task, udc,((&udc_task)->fun = (usb_fill_udc_task), (&udc_task
)->arg = (udc), (&udc_task)->type = (0), (&udc_task
)->state = 0x0)
725 USB_TASK_TYPE_GENERIC)((&udc_task)->fun = (usb_fill_udc_task), (&udc_task
)->arg = (udc), (&udc_task)->type = (0), (&udc_task
)->state = 0x0)
;
726 usb_add_task(sc->sc_bus->root_hub, &udc_task);
727 usb_wait_task(sc->sc_bus->root_hub, &udc_task);
728 if (udc->udc_desc.bLength == 0)
729 return (EINVAL22);
730 break;
731 }
732
733 case USB_DEVICE_GET_FDESC(((unsigned long)0x80000000|(unsigned long)0x40000000) | ((sizeof
(struct usb_device_fdesc) & 0x1fff) << 16) | ((('U'
)) << 8) | ((7)))
:
734 {
735 struct usb_device_fdesc *udf = (struct usb_device_fdesc *)data;
736 int addr = udf->udf_addr;
737 struct usb_task udf_task;
738 struct usb_device_fdesc save_udf;
739 usb_config_descriptor_t *cdesc;
740 struct iovec iov;
741 struct uio uio;
742 size_t len, cdesc_len;
743
744 if (addr < 1 || addr >= USB_MAX_DEVICES128)
745 return (EINVAL22);
746 if (sc->sc_bus->devices[addr] == NULL((void *)0))
747 return (ENXIO6);
748
749 udf->udf_bus = unit;
750
751 save_udf = *udf;
752 udf->udf_data = NULL((void *)0);
753 usb_init_task(&udf_task, usb_fill_udf_task, udf,((&udf_task)->fun = (usb_fill_udf_task), (&udf_task
)->arg = (udf), (&udf_task)->type = (0), (&udf_task
)->state = 0x0)
754 USB_TASK_TYPE_GENERIC)((&udf_task)->fun = (usb_fill_udf_task), (&udf_task
)->arg = (udf), (&udf_task)->type = (0), (&udf_task
)->state = 0x0)
;
755 usb_add_task(sc->sc_bus->root_hub, &udf_task);
756 usb_wait_task(sc->sc_bus->root_hub, &udf_task);
757 len = cdesc_len = udf->udf_size;
758 cdesc = (usb_config_descriptor_t *)udf->udf_data;
759 *udf = save_udf;
760 if (cdesc == NULL((void *)0))
761 return (EINVAL22);
762 if (len > udf->udf_size)
763 len = udf->udf_size;
764 iov.iov_base = (caddr_t)udf->udf_data;
765 iov.iov_len = len;
766 uio.uio_iov = &iov;
767 uio.uio_iovcnt = 1;
768 uio.uio_resid = len;
769 uio.uio_offset = 0;
770 uio.uio_segflg = UIO_USERSPACE;
771 uio.uio_rw = UIO_READ;
772 uio.uio_procp = p;
773 error = uiomove((void *)cdesc, len, &uio);
774 free(cdesc, M_TEMP127, cdesc_len);
775 return (error);
776 }
777
778 default:
779 return (EINVAL22);
780 }
781 return (0);
782}
783
784/*
785 * Explore device tree from the root. We need mutual exclusion to this
786 * hub while traversing the device tree, but this is guaranteed since this
787 * function is only called from the task thread, with one exception:
788 * usb_attach() calls this function, but there shouldn't be anything else
789 * trying to explore this hub at that time.
790 */
791void
792usb_explore(void *v)
793{
794 struct usb_softc *sc = v;
795 struct timeval now, waited;
796 int pwrdly, waited_ms;
797
798 DPRINTFN(2,("%s: %s\n", __func__, sc->sc_dev.dv_xname));
799#ifdef USB_DEBUG
800 if (usb_noexplore)
801 return;
802#endif
803
804 if (sc->sc_bus->dying)
805 return;
806
807 if (sc->sc_bus->flags & USB_BUS_CONFIG_PENDING0x01) {
808 /*
809 * If this is a low/full speed hub and there is a high
810 * speed hub that hasn't explored yet, reschedule this
811 * task, allowing the high speed explore task to run.
812 */
813 if (sc->sc_bus->usbrev < USBREV_2_04 && explore_pending > 0) {
814 usb_add_task(sc->sc_bus->root_hub,
815 &sc->sc_explore_task);
816 return;
817 }
818
819 /*
820 * Wait for power to stabilize.
821 */
822 getmicrouptime(&now);
823 timersub(&now, &sc->sc_ptime, &waited)do { (&waited)->tv_sec = (&now)->tv_sec - (&
sc->sc_ptime)->tv_sec; (&waited)->tv_usec = (&
now)->tv_usec - (&sc->sc_ptime)->tv_usec; if ((&
waited)->tv_usec < 0) { (&waited)->tv_sec--; (&
waited)->tv_usec += 1000000; } } while (0)
;
824 waited_ms = waited.tv_sec * 1000 + waited.tv_usec / 1000;
825
826 pwrdly = sc->sc_bus->root_hub->hub->powerdelay +
827 USB_EXTRA_POWER_UP_TIME20;
828 if (pwrdly > waited_ms)
829 usb_delay_ms(sc->sc_bus, pwrdly - waited_ms);
830 }
831
832 if (sc->sc_bus->flags & USB_BUS_DISCONNECTING0x02) {
833 /* Prevent new tasks from being scheduled. */
834 sc->sc_bus->dying = 1;
835
836 /* Make all devices disconnect. */
837 if (sc->sc_port.device != NULL((void *)0)) {
838 usbd_detach(sc->sc_port.device, (struct device *)sc);
839 sc->sc_port.device = NULL((void *)0);
840 }
841
842 sc->sc_bus->flags &= ~USB_BUS_DISCONNECTING0x02;
843 } else {
844 sc->sc_bus->root_hub->hub->explore(sc->sc_bus->root_hub);
845 }
846
847 if (sc->sc_bus->flags & USB_BUS_CONFIG_PENDING0x01) {
848 DPRINTF(("%s: %s: first explore done\n", __func__,
849 sc->sc_dev.dv_xname));
850 if (sc->sc_bus->usbrev == USBREV_2_04 && explore_pending)
851 explore_pending--;
852 config_pending_decr();
853 sc->sc_bus->flags &= ~(USB_BUS_CONFIG_PENDING0x01);
854 }
855}
856
857void
858usb_needs_explore(struct usbd_device *dev, int first_explore)
859{
860 struct usb_softc *usbctl = (struct usb_softc *)dev->bus->usbctl;
861
862 DPRINTFN(3,("%s: %s\n", usbctl->sc_dev.dv_xname, __func__));
863
864 if (!first_explore && (dev->bus->flags & USB_BUS_CONFIG_PENDING0x01)) {
865 DPRINTF(("%s: %s: not exploring before first explore\n",
866 __func__, usbctl->sc_dev.dv_xname));
867 return;
868 }
869
870 usb_add_task(dev, &usbctl->sc_explore_task);
871}
872
873void
874usb_needs_reattach(struct usbd_device *dev)
875{
876 DPRINTFN(2,("usb_needs_reattach\n"));
877 dev->powersrc->reattach = 1;
878 usb_needs_explore(dev, 0);
879}
880
881void
882usb_schedsoftintr(struct usbd_bus *bus)
883{
884 DPRINTFN(10,("%s: polling=%d\n", __func__, bus->use_polling));
885
886 /* In case usb(4) is disabled */
887 if (bus->soft == NULL((void *)0))
888 return;
889
890 if (bus->use_polling) {
891 bus->methods->soft_intr(bus);
892 } else {
893 softintr_schedule(bus->soft)do { struct x86_soft_intrhand *__sih = (bus->soft); struct
x86_soft_intr *__si = __sih->sih_intrhead; mtx_enter(&
__si->softintr_lock); if (__sih->sih_pending == 0) { do
{ (__sih)->sih_q.tqe_next = ((void *)0); (__sih)->sih_q
.tqe_prev = (&__si->softintr_q)->tqh_last; *(&__si
->softintr_q)->tqh_last = (__sih); (&__si->softintr_q
)->tqh_last = &(__sih)->sih_q.tqe_next; } while (0)
; __sih->sih_pending = 1; softintr(__si->softintr_ssir)
; } mtx_leave(&__si->softintr_lock); } while ( 0)
;
894 }
895}
896
897int
898usb_activate(struct device *self, int act)
899{
900 struct usb_softc *sc = (struct usb_softc *)self;
901 int rv = 0;
902
903 switch (act) {
904 case DVACT_QUIESCE2:
905 if (sc->sc_bus->root_hub != NULL((void *)0))
906 usb_detach_roothub(sc);
907 break;
908 case DVACT_RESUME4:
909 sc->sc_bus->dying = 0;
910
911 /*
912 * Make sure the root hub is present before interrupts
913 * get enabled. As long as the bus is in polling mode
914 * it is safe to call usbd_new_device() now since root
915 * hub transfers do not need to sleep.
916 */
917 sc->sc_bus->use_polling++;
918 if (!usb_attach_roothub(sc))
919 usb_needs_explore(sc->sc_bus->root_hub, 0);
920 sc->sc_bus->use_polling--;
921 break;
922 default:
923 rv = config_activate_children(self, act);
924 break;
925 }
926 return (rv);
927}
928
929int
930usb_detach(struct device *self, int flags)
931{
932 struct usb_softc *sc = (struct usb_softc *)self;
933
934 if (sc->sc_bus->root_hub != NULL((void *)0)) {
935 usb_detach_roothub(sc);
936
937 if (--usb_nbuses == 0) {
938 usb_run_tasks = usb_run_abort_tasks = 0;
939 wakeup(&usb_run_abort_tasks);
940 wakeup(&usb_run_tasks);
941 }
942 }
943
944 if (sc->sc_bus->soft != NULL((void *)0)) {
945 softintr_disestablish(sc->sc_bus->soft);
946 sc->sc_bus->soft = NULL((void *)0);
947 }
948
949#if NBPFILTER1 > 0
950 bpfsdetach(sc->sc_bus->bpfif);
951#endif
952 return (0);
953}
954
955void
956usb_tap(struct usbd_bus *bus, struct usbd_xfer *xfer, uint8_t dir)
957{
958#if NBPFILTER1 > 0
959 struct usb_softc *sc = (struct usb_softc *)bus->usbctl;
960 usb_endpoint_descriptor_t *ed = xfer->pipe->endpoint->edesc;
961 union {
962 struct usbpcap_ctl_hdr uch;
963 struct usbpcap_iso_hdr_full uih;
964 } h;
965 struct usbpcap_pkt_hdr *uph = &h.uch.uch_hdr;
966 uint32_t nframes, offset;
967 unsigned int bpfdir;
968 void *data = NULL((void *)0);
969 size_t flen;
970 caddr_t bpf;
971 int i;
972
973 bpf = bus->bpf;
974 if (bpf == NULL((void *)0))
975 return;
976
977 switch (UE_GET_XFERTYPE(ed->bmAttributes)((ed->bmAttributes) & 0x03)) {
978 case UE_CONTROL0x00:
979 /* Control transfer headers include an extra byte */
980 uph->uph_hlen = htole16(sizeof(struct usbpcap_ctl_hdr))((__uint16_t)(sizeof(struct usbpcap_ctl_hdr)));
981 uph->uph_xfertype = USBPCAP_TRANSFER_CONTROL2;
982 break;
983 case UE_ISOCHRONOUS0x01:
984 offset = 0;
985 nframes = xfer->nframes;
986#ifdef DIAGNOSTIC1
987 if (nframes > _USBPCAP_MAX_ISOFRAMES40) {
988 printf("%s: too many frames: %d > %d\n", __func__,
989 xfer->nframes, _USBPCAP_MAX_ISOFRAMES40);
990 nframes = _USBPCAP_MAX_ISOFRAMES40;
991 }
992#endif
993 /* Isochronous transfer headers include space for one frame */
994 flen = (nframes - 1) * sizeof(struct usbpcap_iso_pkt);
995 uph->uph_hlen = htole16(sizeof(struct usbpcap_iso_hdr) + flen)((__uint16_t)(sizeof(struct usbpcap_iso_hdr) + flen));
996 uph->uph_xfertype = USBPCAP_TRANSFER_ISOCHRONOUS0;
997 h.uih.uih_startframe = 0; /* not yet used */
998 h.uih.uih_nframes = nframes;
999 h.uih.uih_errors = 0; /* we don't have per-frame error */
1000 for (i = 0; i < nframes; i++) {
1001 h.uih.uih_frames[i].uip_offset = offset;
1002 h.uih.uih_frames[i].uip_length = xfer->frlengths[i];
1003 /* See above, we don't have per-frame error */
1004 h.uih.uih_frames[i].uip_status = 0;
1005 offset += xfer->frlengths[i];
1006 }
1007 break;
1008 case UE_BULK0x02:
1009 uph->uph_hlen = htole16(sizeof(*uph))((__uint16_t)(sizeof(*uph)));
1010 uph->uph_xfertype = USBPCAP_TRANSFER_BULK3;
1011 break;
1012 case UE_INTERRUPT0x03:
1013 uph->uph_hlen = htole16(sizeof(*uph))((__uint16_t)(sizeof(*uph)));
1014 uph->uph_xfertype = USBPCAP_TRANSFER_INTERRUPT1;
1015 break;
1016 default:
1017 return;
1018 }
1019
1020 uph->uph_id = 0; /* not yet used */
1021 uph->uph_status = htole32(xfer->status)((__uint32_t)(xfer->status));
1022 uph->uph_function = 0; /* not yet used */
1023 uph->uph_bus = htole32(sc->sc_dev.dv_unit)((__uint32_t)(sc->sc_dev.dv_unit));
1024 uph->uph_devaddr = htole16(xfer->device->address)((__uint16_t)(xfer->device->address));
1025 uph->uph_epaddr = ed->bEndpointAddress;
1026 uph->uph_info = 0;
1027
1028 /* Outgoing control requests start with a STAGE dump. */
1029 if ((xfer->rqflags & URQ_REQUEST0x01) && (dir == USBTAP_DIR_OUT0)) {
1030 h.uch.uch_stage = USBPCAP_CONTROL_STAGE_SETUP0;
1031 uph->uph_dlen = sizeof(usb_device_request_t);
1032 bpf_tap_hdr(bpf, uph, uph->uph_hlen, &xfer->request,
1033 uph->uph_dlen, BPF_DIRECTION_OUT(1 << 1));
1034 }
1035
1036 if (dir == USBTAP_DIR_OUT0) {
1037 bpfdir = BPF_DIRECTION_OUT(1 << 1);
1038 if (!usbd_xfer_isread(xfer)) {
1039 data = KERNADDR(&xfer->dmabuf, 0)((void *)((char *)((&xfer->dmabuf)->block->kaddr
+ (&xfer->dmabuf)->offs) + (0)))
;
1040 uph->uph_dlen = xfer->length;
1041 if (xfer->rqflags & URQ_REQUEST0x01)
1042 h.uch.uch_stage = USBPCAP_CONTROL_STAGE_DATA1;
1043 } else {
1044 data = NULL((void *)0);
1045 uph->uph_dlen = 0;
1046 if (xfer->rqflags & URQ_REQUEST0x01)
1047 h.uch.uch_stage = USBPCAP_CONTROL_STAGE_STATUS2;
1048 }
1049 } else { /* USBTAP_DIR_IN */
1050 bpfdir = BPF_DIRECTION_IN(1 << 0);
1051 uph->uph_info = USBPCAP_INFO_DIRECTION_IN(1 << 0);
1052 if (usbd_xfer_isread(xfer)) {
1053 data = KERNADDR(&xfer->dmabuf, 0)((void *)((char *)((&xfer->dmabuf)->block->kaddr
+ (&xfer->dmabuf)->offs) + (0)))
;
1054 uph->uph_dlen = xfer->actlen;
1055 if (xfer->rqflags & URQ_REQUEST0x01)
1056 h.uch.uch_stage = USBPCAP_CONTROL_STAGE_DATA1;
1057 } else {
1058 data = NULL((void *)0);
1059 uph->uph_dlen = 0;
1060 if (xfer->rqflags & URQ_REQUEST0x01)
1061 h.uch.uch_stage = USBPCAP_CONTROL_STAGE_STATUS2;
1062 }
1063 }
1064
1065 /* Dump bulk/intr/iso data, ctrl DATA or STATUS stage. */
1066 bpf_tap_hdr(bpf, uph, uph->uph_hlen, data, uph->uph_dlen, bpfdir);
1067
1068 /* Incoming control requests with DATA need a STATUS stage. */
1069 if ((xfer->rqflags & URQ_REQUEST0x01) && (dir == USBTAP_DIR_IN1) &&
1070 (h.uch.uch_stage == USBPCAP_CONTROL_STAGE_DATA1)) {
1071 h.uch.uch_stage = USBPCAP_CONTROL_STAGE_STATUS2;
1072 uph->uph_dlen = 0;
1073 bpf_tap_hdr(bpf, uph, uph->uph_hlen, NULL((void *)0), 0, BPF_DIRECTION_IN(1 << 0));
1074 }
1075#endif
1076}