Bug Summary

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