Bug Summary

File:dev/usb/ehci.c
Warning:line 1875, column 54
Access to field 'bDescriptorType' results in a dereference of a null pointer (loaded from variable 'buf')

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 ehci.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/ehci.c
1/* $OpenBSD: ehci.c,v 1.218 2022/01/09 05:43:00 jsg Exp $ */
2/* $NetBSD: ehci.c,v 1.66 2004/06/30 03:11:56 mycroft Exp $ */
3
4/*
5 * Copyright (c) 2014-2015 Martin Pieuchot
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19/*
20 * Copyright (c) 2004-2008 The NetBSD Foundation, Inc.
21 * All rights reserved.
22 *
23 * This code is derived from software contributed to The NetBSD Foundation
24 * by Lennart Augustsson (lennart@augustsson.net), Charles M. Hannum and
25 * Jeremy Morse (jeremy.morse@gmail.com).
26 *
27 * Redistribution and use in source and binary forms, with or without
28 * modification, are permitted provided that the following conditions
29 * are met:
30 * 1. Redistributions of source code must retain the above copyright
31 * notice, this list of conditions and the following disclaimer.
32 * 2. Redistributions in binary form must reproduce the above copyright
33 * notice, this list of conditions and the following disclaimer in the
34 * documentation and/or other materials provided with the distribution.
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
37 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
38 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
40 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
41 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
42 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
43 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
44 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 * POSSIBILITY OF SUCH DAMAGE.
47 */
48
49/*
50 * TODO:
51 * 1) The hub driver needs to handle and schedule the transaction translator,
52 * to assign place in frame where different devices get to go. See chapter
53 * on hubs in USB 2.0 for details.
54 *
55 * 2) Command failures are not recovered correctly.
56 */
57
58#include <sys/param.h>
59#include <sys/systm.h>
60#include <sys/kernel.h>
61#include <sys/rwlock.h>
62#include <sys/malloc.h>
63#include <sys/device.h>
64#include <sys/queue.h>
65#include <sys/timeout.h>
66#include <sys/pool.h>
67#include <sys/endian.h>
68#include <sys/atomic.h>
69
70#include <machine/bus.h>
71
72#include <dev/usb/usb.h>
73#include <dev/usb/usbdi.h>
74#include <dev/usb/usbdivar.h>
75#include <dev/usb/usb_mem.h>
76
77#include <dev/usb/ehcireg.h>
78#include <dev/usb/ehcivar.h>
79
80struct cfdriver ehci_cd = {
81 NULL((void *)0), "ehci", DV_DULL, CD_SKIPHIBERNATE2
82};
83
84#ifdef EHCI_DEBUG
85#define DPRINTF(x) do { if (ehcidebug) printf x; } while(0)
86#define DPRINTFN(n,x) do { if (ehcidebug>(n)) printf x; } while (0)
87int ehcidebug = 0;
88#define bitmask_snprintf(q,f,b,l) snprintf((b), (l), "%b", (q), (f))
89#else
90#define DPRINTF(x)
91#define DPRINTFN(n,x)
92#endif
93
94struct pool *ehcixfer;
95
96struct ehci_pipe {
97 struct usbd_pipe pipe;
98
99 struct ehci_soft_qh *sqh;
100 union {
101 /* Control pipe */
102 struct {
103 struct usb_dma reqdma;
104 } ctl;
105 /* Iso pipe */
106 struct {
107 u_int next_frame;
108 u_int cur_xfers;
109 } isoc;
110 } u;
111};
112
113u_int8_t ehci_reverse_bits(u_int8_t, int);
114
115usbd_status ehci_open(struct usbd_pipe *);
116int ehci_setaddr(struct usbd_device *, int);
117void ehci_poll(struct usbd_bus *);
118void ehci_softintr(void *);
119int ehci_intr1(struct ehci_softc *);
120void ehci_check_intr(struct ehci_softc *, struct usbd_xfer *);
121void ehci_check_qh_intr(struct ehci_softc *, struct usbd_xfer *);
122void ehci_check_itd_intr(struct ehci_softc *, struct usbd_xfer *);
123void ehci_idone(struct usbd_xfer *);
124void ehci_isoc_idone(struct usbd_xfer *);
125void ehci_timeout(void *);
126void ehci_timeout_task(void *);
127void ehci_intrlist_timeout(void *);
128
129struct usbd_xfer *ehci_allocx(struct usbd_bus *);
130void ehci_freex(struct usbd_bus *, struct usbd_xfer *);
131
132usbd_status ehci_root_ctrl_transfer(struct usbd_xfer *);
133usbd_status ehci_root_ctrl_start(struct usbd_xfer *);
134void ehci_root_ctrl_abort(struct usbd_xfer *);
135void ehci_root_ctrl_close(struct usbd_pipe *);
136void ehci_root_ctrl_done(struct usbd_xfer *);
137
138usbd_status ehci_root_intr_transfer(struct usbd_xfer *);
139usbd_status ehci_root_intr_start(struct usbd_xfer *);
140void ehci_root_intr_abort(struct usbd_xfer *);
141void ehci_root_intr_close(struct usbd_pipe *);
142void ehci_root_intr_done(struct usbd_xfer *);
143
144usbd_status ehci_device_ctrl_transfer(struct usbd_xfer *);
145usbd_status ehci_device_ctrl_start(struct usbd_xfer *);
146void ehci_device_ctrl_abort(struct usbd_xfer *);
147void ehci_device_ctrl_close(struct usbd_pipe *);
148void ehci_device_ctrl_done(struct usbd_xfer *);
149
150usbd_status ehci_device_bulk_transfer(struct usbd_xfer *);
151usbd_status ehci_device_bulk_start(struct usbd_xfer *);
152void ehci_device_bulk_abort(struct usbd_xfer *);
153void ehci_device_bulk_close(struct usbd_pipe *);
154void ehci_device_bulk_done(struct usbd_xfer *);
155
156usbd_status ehci_device_intr_transfer(struct usbd_xfer *);
157usbd_status ehci_device_intr_start(struct usbd_xfer *);
158void ehci_device_intr_abort(struct usbd_xfer *);
159void ehci_device_intr_close(struct usbd_pipe *);
160void ehci_device_intr_done(struct usbd_xfer *);
161
162usbd_status ehci_device_isoc_transfer(struct usbd_xfer *);
163usbd_status ehci_device_isoc_start(struct usbd_xfer *);
164void ehci_device_isoc_abort(struct usbd_xfer *);
165void ehci_device_isoc_close(struct usbd_pipe *);
166void ehci_device_isoc_done(struct usbd_xfer *);
167
168void ehci_device_clear_toggle(struct usbd_pipe *pipe);
169
170void ehci_pcd(struct ehci_softc *, struct usbd_xfer *);
171void ehci_disown(struct ehci_softc *, int, int);
172
173struct ehci_soft_qh *ehci_alloc_sqh(struct ehci_softc *);
174void ehci_free_sqh(struct ehci_softc *, struct ehci_soft_qh *);
175
176struct ehci_soft_qtd *ehci_alloc_sqtd(struct ehci_softc *);
177void ehci_free_sqtd(struct ehci_softc *, struct ehci_soft_qtd *);
178usbd_status ehci_alloc_sqtd_chain(struct ehci_softc *, u_int,
179 struct usbd_xfer *, struct ehci_soft_qtd **, struct ehci_soft_qtd **);
180void ehci_free_sqtd_chain(struct ehci_softc *, struct ehci_xfer *);
181
182struct ehci_soft_itd *ehci_alloc_itd(struct ehci_softc *);
183void ehci_free_itd(struct ehci_softc *, struct ehci_soft_itd *);
184void ehci_rem_itd_chain(struct ehci_softc *, struct ehci_xfer *);
185void ehci_free_itd_chain(struct ehci_softc *, struct ehci_xfer *);
186int ehci_alloc_itd_chain(struct ehci_softc *, struct usbd_xfer *);
187int ehci_alloc_sitd_chain(struct ehci_softc *, struct usbd_xfer *);
188void ehci_abort_isoc_xfer(struct usbd_xfer *xfer,
189 usbd_status status);
190
191usbd_status ehci_device_setintr(struct ehci_softc *, struct ehci_soft_qh *,
192 int ival);
193
194void ehci_add_qh(struct ehci_soft_qh *, struct ehci_soft_qh *);
195void ehci_rem_qh(struct ehci_softc *, struct ehci_soft_qh *);
196void ehci_set_qh_qtd(struct ehci_soft_qh *, struct ehci_soft_qtd *);
197void ehci_sync_hc(struct ehci_softc *);
198
199void ehci_close_pipe(struct usbd_pipe *);
200void ehci_abort_xfer(struct usbd_xfer *, usbd_status);
201
202#ifdef EHCI_DEBUG
203void ehci_dump_regs(struct ehci_softc *);
204void ehci_dump(void);
205struct ehci_softc *theehci;
206void ehci_dump_link(ehci_link_t, int);
207void ehci_dump_sqtds(struct ehci_soft_qtd *);
208void ehci_dump_sqtd(struct ehci_soft_qtd *);
209void ehci_dump_qtd(struct ehci_qtd *);
210void ehci_dump_sqh(struct ehci_soft_qh *);
211#if notyet
212void ehci_dump_itd(struct ehci_soft_itd *);
213#endif
214#ifdef DIAGNOSTIC1
215void ehci_dump_exfer(struct ehci_xfer *);
216#endif
217#endif
218
219#define EHCI_INTR_ENDPT1 1
220
221struct usbd_bus_methods ehci_bus_methods = {
222 .open_pipe = ehci_open,
223 .dev_setaddr = ehci_setaddr,
224 .soft_intr = ehci_softintr,
225 .do_poll = ehci_poll,
226 .allocx = ehci_allocx,
227 .freex = ehci_freex,
228};
229
230struct usbd_pipe_methods ehci_root_ctrl_methods = {
231 .transfer = ehci_root_ctrl_transfer,
232 .start = ehci_root_ctrl_start,
233 .abort = ehci_root_ctrl_abort,
234 .close = ehci_root_ctrl_close,
235 .done = ehci_root_ctrl_done,
236};
237
238struct usbd_pipe_methods ehci_root_intr_methods = {
239 .transfer = ehci_root_intr_transfer,
240 .start = ehci_root_intr_start,
241 .abort = ehci_root_intr_abort,
242 .close = ehci_root_intr_close,
243 .done = ehci_root_intr_done,
244};
245
246struct usbd_pipe_methods ehci_device_ctrl_methods = {
247 .transfer = ehci_device_ctrl_transfer,
248 .start = ehci_device_ctrl_start,
249 .abort = ehci_device_ctrl_abort,
250 .close = ehci_device_ctrl_close,
251 .done = ehci_device_ctrl_done,
252};
253
254struct usbd_pipe_methods ehci_device_intr_methods = {
255 .transfer = ehci_device_intr_transfer,
256 .start = ehci_device_intr_start,
257 .abort = ehci_device_intr_abort,
258 .close = ehci_device_intr_close,
259 .cleartoggle = ehci_device_clear_toggle,
260 .done = ehci_device_intr_done,
261};
262
263struct usbd_pipe_methods ehci_device_bulk_methods = {
264 .transfer = ehci_device_bulk_transfer,
265 .start = ehci_device_bulk_start,
266 .abort = ehci_device_bulk_abort,
267 .close = ehci_device_bulk_close,
268 .cleartoggle = ehci_device_clear_toggle,
269 .done = ehci_device_bulk_done,
270};
271
272struct usbd_pipe_methods ehci_device_isoc_methods = {
273 .transfer = ehci_device_isoc_transfer,
274 .start = ehci_device_isoc_start,
275 .abort = ehci_device_isoc_abort,
276 .close = ehci_device_isoc_close,
277 .done = ehci_device_isoc_done,
278};
279
280/*
281 * Reverse a number with nbits bits. Used to evenly distribute lower-level
282 * interrupt heads in the periodic schedule.
283 * Suitable for use with EHCI_IPOLLRATES <= 9.
284 */
285u_int8_t
286ehci_reverse_bits(u_int8_t c, int nbits)
287{
288 c = ((c >> 1) & 0x55) | ((c << 1) & 0xaa);
289 c = ((c >> 2) & 0x33) | ((c << 2) & 0xcc);
290 c = ((c >> 4) & 0x0f) | ((c << 4) & 0xf0);
291
292 return c >> (8 - nbits);
293}
294
295usbd_status
296ehci_init(struct ehci_softc *sc)
297{
298 u_int32_t sparams, cparams, hcr;
299 u_int i, j;
300 usbd_status err;
301 struct ehci_soft_qh *sqh;
302
303#ifdef EHCI_DEBUG
304 u_int32_t vers;
305 theehci = sc;
306
307 DPRINTF(("ehci_init: start\n"));
308
309 vers = EREAD2(sc, EHCI_HCIVERSION)(((sc)->iot)->read_2(((sc)->ioh), ((0x02))));
310 DPRINTF(("%s: EHCI version %x.%x\n", sc->sc_bus.bdev.dv_xname,
311 vers >> 8, vers & 0xff));
312#endif
313
314 sc->sc_offs = EREAD1(sc, EHCI_CAPLENGTH)(((sc)->iot)->read_1(((sc)->ioh), ((0x00))));
315
316 sparams = EREAD4(sc, EHCI_HCSPARAMS)(((sc)->iot)->read_4(((sc)->ioh), ((0x04))));
317 DPRINTF(("ehci_init: sparams=0x%x\n", sparams));
318 sc->sc_noport = EHCI_HCS_N_PORTS(sparams)((sparams) & 0xf);
319 cparams = EREAD4(sc, EHCI_HCCPARAMS)(((sc)->iot)->read_4(((sc)->ioh), ((0x08))));
320 DPRINTF(("ehci_init: cparams=0x%x\n", cparams));
321
322 /* MUST clear segment register if 64 bit capable. */
323 if (EHCI_HCC_64BIT(cparams)((cparams) & 0x1))
324 EWRITE4(sc, EHCI_CTRLDSSEGMENT, 0)(((sc)->iot)->write_4(((sc)->ioh), ((0x10)), ((0))));
325
326 sc->sc_bus.usbrev = USBREV_2_04;
327
328 DPRINTF(("%s: resetting\n", sc->sc_bus.bdev.dv_xname));
329 err = ehci_reset(sc);
330 if (err)
331 return (err);
332
333 if (ehcixfer == NULL((void *)0)) {
334 ehcixfer = malloc(sizeof(struct pool), M_USBHC103, M_NOWAIT0x0002);
335 if (ehcixfer == NULL((void *)0)) {
336 printf("%s: unable to allocate pool descriptor\n",
337 sc->sc_bus.bdev.dv_xname);
338 return (ENOMEM12);
339 }
340 pool_init(ehcixfer, sizeof(struct ehci_xfer), 0, IPL_SOFTUSB0x5,
341 0, "ehcixfer", NULL((void *)0));
342 }
343
344 /* frame list size at default, read back what we got and use that */
345 switch (EHCI_CMD_FLS(EOREAD4(sc, EHCI_USBCMD))((((((sc)->iot)->read_4(((sc)->ioh), ((sc)->sc_offs
+(0x00))))) >> 2) & 3)
) {
346 case 0:
347 sc->sc_flsize = 1024;
348 break;
349 case 1:
350 sc->sc_flsize = 512;
351 break;
352 case 2:
353 sc->sc_flsize = 256;
354 break;
355 case 3:
356 return (USBD_IOERROR);
357 }
358 err = usb_allocmem(&sc->sc_bus, sc->sc_flsize * sizeof(ehci_link_t),
359 EHCI_FLALIGN_ALIGN0x1000, USB_DMA_COHERENT(1 << 0), &sc->sc_fldma);
360 if (err)
361 return (err);
362 DPRINTF(("%s: flsize=%d\n", sc->sc_bus.bdev.dv_xname,sc->sc_flsize));
363 sc->sc_flist = KERNADDR(&sc->sc_fldma, 0)((void *)((char *)((&sc->sc_fldma)->block->kaddr
+ (&sc->sc_fldma)->offs) + (0)))
;
364
365 for (i = 0; i < sc->sc_flsize; i++)
366 sc->sc_flist[i] = htole32(EHCI_LINK_TERMINATE)((__uint32_t)(0x00000001));
367
368 EOWRITE4(sc, EHCI_PERIODICLISTBASE, DMAADDR(&sc->sc_fldma, 0))(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(0x14)), ((((&sc->sc_fldma)->block->map->dm_segs
[0].ds_addr + (&sc->sc_fldma)->offs + (0))))))
;
369
370 sc->sc_softitds = mallocarray(sc->sc_flsize,
371 sizeof(struct ehci_soft_itd *), M_USBHC103, M_NOWAIT0x0002 | M_ZERO0x0008);
372 if (sc->sc_softitds == NULL((void *)0)) {
373 usb_freemem(&sc->sc_bus, &sc->sc_fldma);
374 return (ENOMEM12);
375 }
376 LIST_INIT(&sc->sc_freeitds)do { ((&sc->sc_freeitds)->lh_first) = ((void *)0); }
while (0)
;
377 TAILQ_INIT(&sc->sc_intrhead)do { (&sc->sc_intrhead)->tqh_first = ((void *)0); (
&sc->sc_intrhead)->tqh_last = &(&sc->sc_intrhead
)->tqh_first; } while (0)
;
378
379 /* Set up the bus struct. */
380 sc->sc_bus.methods = &ehci_bus_methods;
381 sc->sc_bus.pipe_size = sizeof(struct ehci_pipe);
382
383 sc->sc_eintrs = EHCI_NORMAL_INTRS(0x00000020 | 0x00000010 | 0x00000004 | 0x00000002 | 0x00000001
)
;
384
385 /*
386 * Allocate the interrupt dummy QHs. These are arranged to give poll
387 * intervals that are powers of 2 times 1ms.
388 */
389 for (i = 0; i < EHCI_INTRQHS((1 << 8) - 1); i++) {
390 sqh = ehci_alloc_sqh(sc);
391 if (sqh == NULL((void *)0)) {
392 err = USBD_NOMEM;
393 goto bad1;
394 }
395 sc->sc_islots[i].sqh = sqh;
396 }
397 for (i = 0; i < EHCI_INTRQHS((1 << 8) - 1); i++) {
398 sqh = sc->sc_islots[i].sqh;
399 if (i == 0) {
400 /* The last (1ms) QH terminates. */
401 sqh->qh.qh_link = htole32(EHCI_LINK_TERMINATE)((__uint32_t)(0x00000001));
402 sqh->next = NULL((void *)0);
403 } else {
404 /* Otherwise the next QH has half the poll interval */
405 sqh->next = sc->sc_islots[(i + 1) / 2 - 1].sqh;
406 sqh->qh.qh_link = htole32(sqh->next->physaddr |((__uint32_t)(sqh->next->physaddr | 0x2))
407 EHCI_LINK_QH)((__uint32_t)(sqh->next->physaddr | 0x2));
408 }
409 sqh->qh.qh_endp = htole32(EHCI_QH_SET_EPS(EHCI_QH_SPEED_HIGH))((__uint32_t)(((0x2) << 12)));
410 sqh->qh.qh_endphub = htole32(EHCI_QH_SET_MULT(1))((__uint32_t)(((1) << 30)));
411 sqh->qh.qh_curqtd = htole32(EHCI_LINK_TERMINATE)((__uint32_t)(0x00000001));
412 sqh->qh.qh_qtd.qtd_next = htole32(EHCI_LINK_TERMINATE)((__uint32_t)(0x00000001));
413 sqh->qh.qh_qtd.qtd_altnext = htole32(EHCI_LINK_TERMINATE)((__uint32_t)(0x00000001));
414 sqh->qh.qh_qtd.qtd_status = htole32(EHCI_QTD_HALTED)((__uint32_t)(0x40));
415 sqh->sqtd = NULL((void *)0);
416 usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh),
417 BUS_DMASYNC_PREWRITE0x04 | BUS_DMASYNC_PREREAD0x01);
418 }
419 /* Point the frame list at the last level (128ms). */
420 for (i = 0; i < (1 << (EHCI_IPOLLRATES8 - 1)); i++)
421 for (j = i; j < sc->sc_flsize; j += 1 << (EHCI_IPOLLRATES8 - 1))
422 sc->sc_flist[j] = htole32(EHCI_LINK_QH | sc->sc_islots[((__uint32_t)(0x2 | sc->sc_islots[ ((((ehci_reverse_bits( i
, 8 - 1)) & ((1 << (8 - 1)) - 1)) | (1 << (8 -
1))) - 1)].sqh->physaddr))
423 EHCI_IQHIDX(EHCI_IPOLLRATES - 1, ehci_reverse_bits(((__uint32_t)(0x2 | sc->sc_islots[ ((((ehci_reverse_bits( i
, 8 - 1)) & ((1 << (8 - 1)) - 1)) | (1 << (8 -
1))) - 1)].sqh->physaddr))
424 i, EHCI_IPOLLRATES - 1))].sqh->physaddr)((__uint32_t)(0x2 | sc->sc_islots[ ((((ehci_reverse_bits( i
, 8 - 1)) & ((1 << (8 - 1)) - 1)) | (1 << (8 -
1))) - 1)].sqh->physaddr))
;
425 usb_syncmem(&sc->sc_fldma, 0, sc->sc_flsize * sizeof(ehci_link_t),
426 BUS_DMASYNC_PREWRITE0x04);
427
428 /* Allocate dummy QH that starts the async list. */
429 sqh = ehci_alloc_sqh(sc);
430 if (sqh == NULL((void *)0)) {
431 err = USBD_NOMEM;
432 goto bad1;
433 }
434 /* Fill the QH */
435 sqh->qh.qh_endp =
436 htole32(EHCI_QH_SET_EPS(EHCI_QH_SPEED_HIGH) | EHCI_QH_HRECL)((__uint32_t)(((0x2) << 12) | 0x00008000));
437 sqh->qh.qh_link =
438 htole32(sqh->physaddr | EHCI_LINK_QH)((__uint32_t)(sqh->physaddr | 0x2));
439 sqh->qh.qh_curqtd = htole32(EHCI_LINK_TERMINATE)((__uint32_t)(0x00000001));
440 sqh->prev = sqh; /*It's a circular list.. */
441 sqh->next = sqh;
442 /* Fill the overlay qTD */
443 sqh->qh.qh_qtd.qtd_next = htole32(EHCI_LINK_TERMINATE)((__uint32_t)(0x00000001));
444 sqh->qh.qh_qtd.qtd_altnext = htole32(EHCI_LINK_TERMINATE)((__uint32_t)(0x00000001));
445 sqh->qh.qh_qtd.qtd_status = htole32(EHCI_QTD_HALTED)((__uint32_t)(0x40));
446 sqh->sqtd = NULL((void *)0);
447 usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh),
448 BUS_DMASYNC_PREWRITE0x04 | BUS_DMASYNC_PREREAD0x01);
449
450 /* Point to async list */
451 sc->sc_async_head = sqh;
452 EOWRITE4(sc, EHCI_ASYNCLISTADDR, sqh->physaddr | EHCI_LINK_QH)(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(0x18)), ((sqh->physaddr | 0x2))))
;
453
454 timeout_set(&sc->sc_tmo_intrlist, ehci_intrlist_timeout, sc);
455
456 rw_init(&sc->sc_doorbell_lock, "ehcidb")_rw_init_flags(&sc->sc_doorbell_lock, "ehcidb", 0, ((void
*)0))
;
457
458 /* Turn on controller */
459 EOWRITE4(sc, EHCI_USBCMD,(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(0x00)), ((0x00020000 | ((((sc)->iot)->read_4(((sc)->
ioh), ((sc)->sc_offs+(0x00)))) & 0x0000000c) | 0x00000020
| 0x00000010 | 0x00000001))))
460 EHCI_CMD_ITC_2 | /* 2 microframes interrupt delay */(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(0x00)), ((0x00020000 | ((((sc)->iot)->read_4(((sc)->
ioh), ((sc)->sc_offs+(0x00)))) & 0x0000000c) | 0x00000020
| 0x00000010 | 0x00000001))))
461 (EOREAD4(sc, EHCI_USBCMD) & EHCI_CMD_FLS_M) |(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(0x00)), ((0x00020000 | ((((sc)->iot)->read_4(((sc)->
ioh), ((sc)->sc_offs+(0x00)))) & 0x0000000c) | 0x00000020
| 0x00000010 | 0x00000001))))
462 EHCI_CMD_ASE |(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(0x00)), ((0x00020000 | ((((sc)->iot)->read_4(((sc)->
ioh), ((sc)->sc_offs+(0x00)))) & 0x0000000c) | 0x00000020
| 0x00000010 | 0x00000001))))
463 EHCI_CMD_PSE |(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(0x00)), ((0x00020000 | ((((sc)->iot)->read_4(((sc)->
ioh), ((sc)->sc_offs+(0x00)))) & 0x0000000c) | 0x00000020
| 0x00000010 | 0x00000001))))
464 EHCI_CMD_RS)(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(0x00)), ((0x00020000 | ((((sc)->iot)->read_4(((sc)->
ioh), ((sc)->sc_offs+(0x00)))) & 0x0000000c) | 0x00000020
| 0x00000010 | 0x00000001))))
;
465
466 /* Take over port ownership */
467 EOWRITE4(sc, EHCI_CONFIGFLAG, EHCI_CONF_CF)(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(0x40)), ((0x00000001))))
;
468
469 for (i = 0; i < 100; i++) {
470 usb_delay_ms(&sc->sc_bus, 1);
471 hcr = EOREAD4(sc, EHCI_USBSTS)(((sc)->iot)->read_4(((sc)->ioh), ((sc)->sc_offs+
(0x04))))
& EHCI_STS_HCH0x00001000;
472 if (!hcr)
473 break;
474 }
475 if (hcr) {
476 printf("%s: run timeout\n", sc->sc_bus.bdev.dv_xname);
477 return (USBD_IOERROR);
478 }
479
480 /* Enable interrupts */
481 EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs)(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(0x08)), ((sc->sc_eintrs))))
;
482
483 return (USBD_NORMAL_COMPLETION);
484
485#if 0
486 bad2:
487 ehci_free_sqh(sc, sc->sc_async_head);
488#endif
489 bad1:
490 free(sc->sc_softitds, M_USBHC103,
491 sc->sc_flsize * sizeof(struct ehci_soft_itd *));
492 usb_freemem(&sc->sc_bus, &sc->sc_fldma);
493 return (err);
494}
495
496int
497ehci_intr(void *v)
498{
499 struct ehci_softc *sc = v;
500
501 if (sc == NULL((void *)0) || sc->sc_bus.dying)
502 return (0);
503
504 /* If we get an interrupt while polling, then just ignore it. */
505 if (sc->sc_bus.use_polling) {
506 u_int32_t intrs = EHCI_STS_INTRS(EOREAD4(sc, EHCI_USBSTS))(((((sc)->iot)->read_4(((sc)->ioh), ((sc)->sc_offs
+(0x04))))) & 0x3f)
;
507
508 if (intrs)
509 EOWRITE4(sc, EHCI_USBSTS, intrs)(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(0x04)), ((intrs))))
; /* Acknowledge */
510 return (0);
511 }
512
513 return (ehci_intr1(sc));
514}
515
516int
517ehci_intr1(struct ehci_softc *sc)
518{
519 u_int32_t intrs, eintrs;
520
521 /* In case the interrupt occurs before initialization has completed. */
522 if (sc == NULL((void *)0)) {
523#ifdef DIAGNOSTIC1
524 printf("ehci_intr1: sc == NULL\n");
525#endif
526 return (0);
527 }
528
529 intrs = EOREAD4(sc, EHCI_USBSTS)(((sc)->iot)->read_4(((sc)->ioh), ((sc)->sc_offs+
(0x04))))
;
530 if (intrs == 0xffffffff) {
531 sc->sc_bus.dying = 1;
532 return (0);
533 }
534 intrs = EHCI_STS_INTRS(intrs)((intrs) & 0x3f);
535 if (!intrs)
536 return (0);
537
538 eintrs = intrs & sc->sc_eintrs;
539 if (!eintrs)
540 return (0);
541
542 EOWRITE4(sc, EHCI_USBSTS, intrs)(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(0x04)), ((intrs))))
; /* Acknowledge */
543 sc->sc_bus.no_intrs++;
544
545 if (eintrs & EHCI_STS_HSE0x00000010) {
546 printf("%s: unrecoverable error, controller halted\n",
547 sc->sc_bus.bdev.dv_xname);
548 sc->sc_bus.dying = 1;
549 return (1);
550 }
551 if (eintrs & EHCI_STS_IAA0x00000020) {
552 wakeup(&sc->sc_async_head);
553 eintrs &= ~EHCI_STS_IAA0x00000020;
554 }
555 if (eintrs & (EHCI_STS_INT0x00000001 | EHCI_STS_ERRINT0x00000002)) {
556 usb_schedsoftintr(&sc->sc_bus);
557 eintrs &= ~(EHCI_STS_INT0x00000001 | EHCI_STS_ERRINT0x00000002);
558 }
559 if (eintrs & EHCI_STS_PCD0x00000004) {
560 atomic_setbits_intx86_atomic_setbits_u32(&sc->sc_flags, EHCIF_PCB_INTR0x02);
561 usb_schedsoftintr(&sc->sc_bus);
562 eintrs &= ~EHCI_STS_PCD0x00000004;
563 }
564
565 if (eintrs != 0) {
566 /* Block unprocessed interrupts. */
567 sc->sc_eintrs &= ~eintrs;
568 EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs)(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(0x08)), ((sc->sc_eintrs))))
;
569 printf("%s: blocking intrs 0x%x\n",
570 sc->sc_bus.bdev.dv_xname, eintrs);
571 }
572
573 return (1);
574}
575
576void
577ehci_pcd(struct ehci_softc *sc, struct usbd_xfer *xfer)
578{
579 u_char *p;
580 int i, m;
581
582 if (xfer == NULL((void *)0)) {
583 /* Just ignore the change. */
584 return;
585 }
586
587 p = KERNADDR(&xfer->dmabuf, 0)((void *)((char *)((&xfer->dmabuf)->block->kaddr
+ (&xfer->dmabuf)->offs) + (0)))
;
588 m = min(sc->sc_noport, xfer->length * 8 - 1);
589 memset(p, 0, xfer->length)__builtin_memset((p), (0), (xfer->length));
590 for (i = 1; i <= m; i++) {
591 /* Pick out CHANGE bits from the status reg. */
592 if (EOREAD4(sc, EHCI_PORTSC(i))(((sc)->iot)->read_4(((sc)->ioh), ((sc)->sc_offs+
((0x40+4*(i))))))
& EHCI_PS_CLEAR(0x00000020|0x00000008|0x00000002))
593 p[i / 8] |= 1 << (i % 8);
594 }
595 xfer->actlen = xfer->length;
596 xfer->status = USBD_NORMAL_COMPLETION;
597
598 usb_transfer_complete(xfer);
599}
600
601/*
602 * Work around the half configured control (default) pipe when setting
603 * the address of a device.
604 *
605 * Because a single QH is setup per endpoint in ehci_open(), and the
606 * control pipe is configured before we could have set the address
607 * of the device or read the wMaxPacketSize of the endpoint, we have
608 * to re-open the pipe twice here.
609 */
610int
611ehci_setaddr(struct usbd_device *dev, int addr)
612{
613 /* Root Hub */
614 if (dev->depth == 0)
615 return (0);
616
617 /* Re-establish the default pipe with the new max packet size. */
618 ehci_close_pipe(dev->default_pipe);
619 if (ehci_open(dev->default_pipe))
620 return (EINVAL22);
621
622 if (usbd_set_address(dev, addr))
623 return (1);
624
625 dev->address = addr;
626
627 /* Re-establish the default pipe with the new address. */
628 ehci_close_pipe(dev->default_pipe);
629 if (ehci_open(dev->default_pipe))
630 return (EINVAL22);
631
632 return (0);
633}
634
635void
636ehci_softintr(void *v)
637{
638 struct ehci_softc *sc = v;
639 struct ehci_xfer *ex, *nextex;
640
641 if (sc->sc_bus.dying)
642 return;
643
644 sc->sc_bus.intr_context++;
645
646 if (sc->sc_flags & EHCIF_PCB_INTR0x02) {
647 atomic_clearbits_intx86_atomic_clearbits_u32(&sc->sc_flags, EHCIF_PCB_INTR0x02);
648 ehci_pcd(sc, sc->sc_intrxfer);
649 }
650
651 /*
652 * The only explanation I can think of for why EHCI is as brain dead
653 * as UHCI interrupt-wise is that Intel was involved in both.
654 * An interrupt just tells us that something is done, we have no
655 * clue what, so we need to scan through all active transfers. :-(
656 */
657 for (ex = TAILQ_FIRST(&sc->sc_intrhead)((&sc->sc_intrhead)->tqh_first); ex; ex = nextex) {
658 nextex = TAILQ_NEXT(ex, inext)((ex)->inext.tqe_next);
659 ehci_check_intr(sc, &ex->xfer);
660 }
661
662 /* Schedule a callout to catch any dropped transactions. */
663 if ((sc->sc_flags & EHCIF_DROPPED_INTR_WORKAROUND0x01) &&
664 !TAILQ_EMPTY(&sc->sc_intrhead)(((&sc->sc_intrhead)->tqh_first) == ((void *)0))) {
665 timeout_add_sec(&sc->sc_tmo_intrlist, 1);
666 }
667
668 if (sc->sc_softwake) {
669 sc->sc_softwake = 0;
670 wakeup(&sc->sc_softwake);
671 }
672
673 sc->sc_bus.intr_context--;
674}
675
676void
677ehci_check_intr(struct ehci_softc *sc, struct usbd_xfer *xfer)
678{
679 int attr = xfer->pipe->endpoint->edesc->bmAttributes;
680
681 if (UE_GET_XFERTYPE(attr)((attr) & 0x03) == UE_ISOCHRONOUS0x01)
682 ehci_check_itd_intr(sc, xfer);
683 else
684 ehci_check_qh_intr(sc, xfer);
685}
686
687void
688ehci_check_qh_intr(struct ehci_softc *sc, struct usbd_xfer *xfer)
689{
690 struct ehci_xfer *ex = (struct ehci_xfer *)xfer;
691 struct ehci_soft_qtd *sqtd, *lsqtd = ex->sqtdend_TD.sqtd.end;
692 uint32_t status;
693
694 KASSERT(ex->sqtdstart != NULL && ex->sqtdend != NULL)((ex->_TD.sqtd.start != ((void *)0) && ex->_TD.
sqtd.end != ((void *)0)) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/dev/usb/ehci.c"
, 694, "ex->sqtdstart != NULL && ex->sqtdend != NULL"
))
;
695
696 usb_syncmem(&lsqtd->dma,
697 lsqtd->offs + offsetof(struct ehci_qtd, qtd_status)__builtin_offsetof(struct ehci_qtd, qtd_status),
698 sizeof(lsqtd->qtd.qtd_status),
699 BUS_DMASYNC_POSTWRITE0x08 | BUS_DMASYNC_POSTREAD0x02);
700
701 /*
702 * If the last TD is still active we need to check whether there
703 * is a an error somewhere in the middle, or whether there was a
704 * short packet (SPD and not ACTIVE).
705 */
706 if (letoh32(lsqtd->qtd.qtd_status)((__uint32_t)(lsqtd->qtd.qtd_status)) & EHCI_QTD_ACTIVE0x80) {
707 DPRINTFN(12, ("ehci_check_intr: active ex=%p\n", ex));
708 for (sqtd = ex->sqtdstart_TD.sqtd.start; sqtd != lsqtd; sqtd=sqtd->nextqtd) {
709 usb_syncmem(&sqtd->dma,
710 sqtd->offs + offsetof(struct ehci_qtd, qtd_status)__builtin_offsetof(struct ehci_qtd, qtd_status),
711 sizeof(sqtd->qtd.qtd_status),
712 BUS_DMASYNC_POSTWRITE0x08 | BUS_DMASYNC_POSTREAD0x02);
713 status = letoh32(sqtd->qtd.qtd_status)((__uint32_t)(sqtd->qtd.qtd_status));
714 usb_syncmem(&sqtd->dma,
715 sqtd->offs + offsetof(struct ehci_qtd, qtd_status)__builtin_offsetof(struct ehci_qtd, qtd_status),
716 sizeof(sqtd->qtd.qtd_status), BUS_DMASYNC_PREREAD0x01);
717 /* If there's an active QTD the xfer isn't done. */
718 if (status & EHCI_QTD_ACTIVE0x80)
719 break;
720 /* Any kind of error makes the xfer done. */
721 if (status & EHCI_QTD_HALTED0x40)
722 goto done;
723 /* We want short packets, and it is short: it's done */
724 if (EHCI_QTD_GET_BYTES(status)(((status) >> 16) & 0x7fff) != 0)
725 goto done;
726 }
727 DPRINTFN(12, ("ehci_check_intr: ex=%p std=%p still active\n",
728 ex, ex->sqtdstart));
729 usb_syncmem(&lsqtd->dma,
730 lsqtd->offs + offsetof(struct ehci_qtd, qtd_status)__builtin_offsetof(struct ehci_qtd, qtd_status),
731 sizeof(lsqtd->qtd.qtd_status), BUS_DMASYNC_PREREAD0x01);
732 return;
733 }
734 done:
735 TAILQ_REMOVE(&sc->sc_intrhead, ex, inext)do { if (((ex)->inext.tqe_next) != ((void *)0)) (ex)->inext
.tqe_next->inext.tqe_prev = (ex)->inext.tqe_prev; else (
&sc->sc_intrhead)->tqh_last = (ex)->inext.tqe_prev
; *(ex)->inext.tqe_prev = (ex)->inext.tqe_next; ((ex)->
inext.tqe_prev) = ((void *)-1); ((ex)->inext.tqe_next) = (
(void *)-1); } while (0)
;
736 timeout_del(&xfer->timeout_handle);
737 usb_rem_task(xfer->pipe->device, &xfer->abort_task);
738 ehci_idone(xfer);
739}
740
741void
742ehci_check_itd_intr(struct ehci_softc *sc, struct usbd_xfer *xfer)
743{
744 struct ehci_xfer *ex = (struct ehci_xfer *)xfer;
745 struct ehci_soft_itd *itd = ex->itdend_TD.itd.end;
746 int i;
747
748 if (xfer != SIMPLEQ_FIRST(&xfer->pipe->queue)((&xfer->pipe->queue)->sqh_first))
749 return;
750
751 KASSERT(ex->itdstart != NULL && ex->itdend != NULL)((ex->_TD.itd.start != ((void *)0) && ex->_TD.itd
.end != ((void *)0)) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/dev/usb/ehci.c"
, 751, "ex->itdstart != NULL && ex->itdend != NULL"
))
;
752
753 /* Check no active transfers in last itd, meaning we're finished */
754 if (xfer->device->speed == USB_SPEED_HIGH3) {
755 usb_syncmem(&itd->dma,
756 itd->offs + offsetof(struct ehci_itd, itd_ctl)__builtin_offsetof(struct ehci_itd, itd_ctl),
757 sizeof(itd->itd.itd_ctl),
758 BUS_DMASYNC_POSTWRITE0x08 | BUS_DMASYNC_POSTREAD0x02);
759
760 for (i = 0; i < 8; i++) {
761 if (letoh32(itd->itd.itd_ctl[i])((__uint32_t)(itd->itd.itd_ctl[i])) & EHCI_ITD_ACTIVE0x80000000)
762 return;
763 }
764 } else {
765 usb_syncmem(&itd->dma,
766 itd->offs + offsetof(struct ehci_sitd, sitd_trans)__builtin_offsetof(struct ehci_sitd, sitd_trans),
767 sizeof(itd->sitd.sitd_trans),
768 BUS_DMASYNC_POSTWRITE0x08 | BUS_DMASYNC_POSTREAD0x02);
769
770 if (le32toh(itd->sitd.sitd_trans)((__uint32_t)(itd->sitd.sitd_trans)) & EHCI_SITD_ACTIVE0x80)
771 return;
772 }
773
774 /* All descriptor(s) inactive, it's done */
775 TAILQ_REMOVE(&sc->sc_intrhead, ex, inext)do { if (((ex)->inext.tqe_next) != ((void *)0)) (ex)->inext
.tqe_next->inext.tqe_prev = (ex)->inext.tqe_prev; else (
&sc->sc_intrhead)->tqh_last = (ex)->inext.tqe_prev
; *(ex)->inext.tqe_prev = (ex)->inext.tqe_next; ((ex)->
inext.tqe_prev) = ((void *)-1); ((ex)->inext.tqe_next) = (
(void *)-1); } while (0)
;
776 timeout_del(&xfer->timeout_handle);
777 usb_rem_task(xfer->pipe->device, &xfer->abort_task);
778 ehci_isoc_idone(xfer);
779}
780
781void
782ehci_isoc_idone(struct usbd_xfer *xfer)
783{
784 struct ehci_xfer *ex = (struct ehci_xfer *)xfer;
785 struct ehci_soft_itd *itd;
786 int i, len, uframes, nframes = 0, actlen = 0;
787 uint32_t status = 0;
788
789 if (xfer->status == USBD_CANCELLED || xfer->status == USBD_TIMEOUT)
790 return;
791
792 if (xfer->device->speed == USB_SPEED_HIGH3) {
793 switch (xfer->pipe->endpoint->edesc->bInterval) {
794 case 0:
795 panic("isoc xfer suddenly has 0 bInterval, invalid");
796 case 1:
797 uframes = 1;
798 break;
799 case 2:
800 uframes = 2;
801 break;
802 case 3:
803 uframes = 4;
804 break;
805 default:
806 uframes = 8;
807 break;
808 }
809
810 for (itd = ex->itdstart_TD.itd.start; itd != NULL((void *)0); itd = itd->xfer_next) {
811 usb_syncmem(&itd->dma,
812 itd->offs + offsetof(struct ehci_itd, itd_ctl)__builtin_offsetof(struct ehci_itd, itd_ctl),
813 sizeof(itd->itd.itd_ctl), BUS_DMASYNC_POSTWRITE0x08 |
814 BUS_DMASYNC_POSTREAD0x02);
815
816 for (i = 0; i < 8; i += uframes) {
817 /* XXX - driver didn't fill in the frame full
818 * of uframes. This leads to scheduling
819 * inefficiencies, but working around
820 * this doubles complexity of tracking
821 * an xfer.
822 */
823 if (nframes >= xfer->nframes)
824 break;
825
826 status = letoh32(itd->itd.itd_ctl[i])((__uint32_t)(itd->itd.itd_ctl[i]));
827 len = EHCI_ITD_GET_LEN(status)(((status) >> 16) & 0xfff);
828 if (EHCI_ITD_GET_STATUS(status)(((status) >> 28) & 0xf) != 0)
829 len = 0; /*No valid data on error*/
830
831 xfer->frlengths[nframes++] = len;
832 actlen += len;
833 }
834 }
835 } else {
836 for (itd = ex->itdstart_TD.itd.start; itd != NULL((void *)0); itd = itd->xfer_next) {
837 usb_syncmem(&itd->dma,
838 itd->offs + offsetof(struct ehci_sitd, sitd_trans)__builtin_offsetof(struct ehci_sitd, sitd_trans),
839 sizeof(itd->sitd.sitd_trans),
840 BUS_DMASYNC_POSTWRITE0x08 | BUS_DMASYNC_POSTREAD0x02);
841
842 status = le32toh(itd->sitd.sitd_trans)((__uint32_t)(itd->sitd.sitd_trans));
843 len = EHCI_SITD_GET_LEN(status)(((status) >> 16) & 0x3ff);
844 if (xfer->frlengths[nframes] >= len)
845 len = xfer->frlengths[nframes] - len;
846 else
847 len = 0;
848
849 xfer->frlengths[nframes++] = len;
850 actlen += len;
851 }
852 }
853
854#ifdef DIAGNOSTIC1
855 ex->isdone = 1;
856#endif
857 xfer->actlen = actlen;
858 xfer->status = USBD_NORMAL_COMPLETION;
859
860 usb_syncmem(&xfer->dmabuf, 0, xfer->length,
861 usbd_xfer_isread(xfer) ?
862 BUS_DMASYNC_POSTREAD0x02 : BUS_DMASYNC_POSTWRITE0x08);
863 usb_transfer_complete(xfer);
864}
865
866void
867ehci_idone(struct usbd_xfer *xfer)
868{
869 struct ehci_xfer *ex = (struct ehci_xfer *)xfer;
870 struct ehci_soft_qtd *sqtd;
871 u_int32_t status = 0, nstatus = 0;
872 int actlen, cerr;
873
874#ifdef DIAGNOSTIC1
875 {
876 int s = splhigh()splraise(0xd);
877 if (ex->isdone) {
878 splx(s)spllower(s);
879 printf("ehci_idone: ex=%p is done!\n", ex);
880 return;
881 }
882 ex->isdone = 1;
883 splx(s)spllower(s);
884 }
885#endif
886 if (xfer->status == USBD_CANCELLED || xfer->status == USBD_TIMEOUT)
887 return;
888
889 actlen = 0;
890 for (sqtd = ex->sqtdstart_TD.sqtd.start; sqtd != NULL((void *)0); sqtd = sqtd->nextqtd) {
891 usb_syncmem(&sqtd->dma, sqtd->offs, sizeof(sqtd->qtd),
892 BUS_DMASYNC_POSTWRITE0x08 | BUS_DMASYNC_POSTREAD0x02);
893 nstatus = letoh32(sqtd->qtd.qtd_status)((__uint32_t)(sqtd->qtd.qtd_status));
894 if (nstatus & EHCI_QTD_ACTIVE0x80)
895 break;
896
897 status = nstatus;
898 /* halt is ok if descriptor is last, and complete */
899 if (sqtd->qtd.qtd_next == htole32(EHCI_LINK_TERMINATE)((__uint32_t)(0x00000001)) &&
900 EHCI_QTD_GET_BYTES(status)(((status) >> 16) & 0x7fff) == 0)
901 status &= ~EHCI_QTD_HALTED0x40;
902 if (EHCI_QTD_GET_PID(status)(((status) >> 8) & 0x3) != EHCI_QTD_PID_SETUP0x2)
903 actlen += sqtd->len - EHCI_QTD_GET_BYTES(status)(((status) >> 16) & 0x7fff);
904 }
905
906 cerr = EHCI_QTD_GET_CERR(status)(((status) >> 10) & 0x3);
907 DPRINTFN(/*10*/2, ("ehci_idone: len=%d, actlen=%d, cerr=%d, "
908 "status=0x%x\n", xfer->length, actlen, cerr, status));
909 xfer->actlen = actlen;
910 if ((status & EHCI_QTD_HALTED0x40) != 0) {
911 if ((status & EHCI_QTD_BABBLE0x10) == 0 && cerr > 0)
912 xfer->status = USBD_STALLED;
913 else
914 xfer->status = USBD_IOERROR; /* more info XXX */
915 } else
916 xfer->status = USBD_NORMAL_COMPLETION;
917
918 if (xfer->actlen)
919 usb_syncmem(&xfer->dmabuf, 0, xfer->actlen,
920 usbd_xfer_isread(xfer) ?
921 BUS_DMASYNC_POSTREAD0x02 : BUS_DMASYNC_POSTWRITE0x08);
922 usb_transfer_complete(xfer);
923 DPRINTFN(/*12*/2, ("ehci_idone: ex=%p done\n", ex));
924}
925
926void
927ehci_poll(struct usbd_bus *bus)
928{
929 struct ehci_softc *sc = (struct ehci_softc *)bus;
930
931 if (EOREAD4(sc, EHCI_USBSTS)(((sc)->iot)->read_4(((sc)->ioh), ((sc)->sc_offs+
(0x04))))
& sc->sc_eintrs)
932 ehci_intr1(sc);
933}
934
935int
936ehci_detach(struct device *self, int flags)
937{
938 struct ehci_softc *sc = (struct ehci_softc *)self;
939 int rv;
940
941 rv = config_detach_children(self, flags);
942 if (rv != 0)
943 return (rv);
944
945 timeout_del(&sc->sc_tmo_intrlist);
946
947 ehci_reset(sc);
948
949 usb_delay_ms(&sc->sc_bus, 300); /* XXX let stray task complete */
950
951 free(sc->sc_softitds, M_USBHC103,
952 sc->sc_flsize * sizeof(struct ehci_soft_itd *));
953 usb_freemem(&sc->sc_bus, &sc->sc_fldma);
954 /* XXX free other data structures XXX */
955
956 return (rv);
957}
958
959
960int
961ehci_activate(struct device *self, int act)
962{
963 struct ehci_softc *sc = (struct ehci_softc *)self;
964 u_int32_t cmd, hcr, cparams;
965 int i, rv = 0;
966
967 switch (act) {
968 case DVACT_SUSPEND3:
969 rv = config_activate_children(self, act);
970
971#ifdef DIAGNOSTIC1
972 if (!TAILQ_EMPTY(&sc->sc_intrhead)(((&sc->sc_intrhead)->tqh_first) == ((void *)0))) {
973 printf("%s: interrupt list not empty\n",
974 sc->sc_bus.bdev.dv_xname);
975 return (-1);
976 }
977#endif
978
979 sc->sc_bus.use_polling++;
980
981 for (i = 1; i <= sc->sc_noport; i++) {
982 cmd = EOREAD4(sc, EHCI_PORTSC(i))(((sc)->iot)->read_4(((sc)->ioh), ((sc)->sc_offs+
((0x40+4*(i))))))
;
983 if ((cmd & (EHCI_PS_PO0x00002000|EHCI_PS_PE0x00000004)) == EHCI_PS_PE0x00000004)
984 EOWRITE4(sc, EHCI_PORTSC(i),(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+((0x40+4*(i)))), ((cmd | 0x00000080))))
985 cmd | EHCI_PS_SUSP)(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+((0x40+4*(i)))), ((cmd | 0x00000080))))
;
986 }
987
988 /*
989 * First tell the host to stop processing Asynchronous
990 * and Periodic schedules.
991 */
992 cmd = EOREAD4(sc, EHCI_USBCMD)(((sc)->iot)->read_4(((sc)->ioh), ((sc)->sc_offs+
(0x00))))
& ~(EHCI_CMD_ASE0x00000020 | EHCI_CMD_PSE0x00000010);
993 EOWRITE4(sc, EHCI_USBCMD, cmd)(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(0x00)), ((cmd))))
;
994 for (i = 0; i < 100; i++) {
995 usb_delay_ms(&sc->sc_bus, 1);
996 hcr = EOREAD4(sc, EHCI_USBSTS)(((sc)->iot)->read_4(((sc)->ioh), ((sc)->sc_offs+
(0x04))))
&
997 (EHCI_STS_ASS0x00008000 | EHCI_STS_PSS0x00004000);
998 if (hcr == 0)
999 break;
1000 }
1001 if (hcr != 0)
1002 printf("%s: disable schedules timeout\n",
1003 sc->sc_bus.bdev.dv_xname);
1004
1005 /*
1006 * Then reset the host as if it was a shutdown.
1007 *
1008 * All USB devices are disconnected/reconnected during
1009 * a suspend/resume cycle so keep it simple.
1010 */
1011 ehci_reset(sc);
1012
1013 sc->sc_bus.use_polling--;
1014 break;
1015 case DVACT_RESUME4:
1016 sc->sc_bus.use_polling++;
1017
1018 ehci_reset(sc);
1019
1020 cparams = EREAD4(sc, EHCI_HCCPARAMS)(((sc)->iot)->read_4(((sc)->ioh), ((0x08))));
1021 /* MUST clear segment register if 64 bit capable. */
1022 if (EHCI_HCC_64BIT(cparams)((cparams) & 0x1))
1023 EWRITE4(sc, EHCI_CTRLDSSEGMENT, 0)(((sc)->iot)->write_4(((sc)->ioh), ((0x10)), ((0))));
1024
1025 EOWRITE4(sc, EHCI_PERIODICLISTBASE, DMAADDR(&sc->sc_fldma, 0))(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(0x14)), ((((&sc->sc_fldma)->block->map->dm_segs
[0].ds_addr + (&sc->sc_fldma)->offs + (0))))))
;
1026 EOWRITE4(sc, EHCI_ASYNCLISTADDR,(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(0x18)), ((sc->sc_async_head->physaddr | 0x2))))
1027 sc->sc_async_head->physaddr | EHCI_LINK_QH)(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(0x18)), ((sc->sc_async_head->physaddr | 0x2))))
;
1028
1029 hcr = 0;
1030 for (i = 1; i <= sc->sc_noport; i++) {
1031 cmd = EOREAD4(sc, EHCI_PORTSC(i))(((sc)->iot)->read_4(((sc)->ioh), ((sc)->sc_offs+
((0x40+4*(i))))))
;
1032 if ((cmd & (EHCI_PS_PO0x00002000|EHCI_PS_SUSP0x00000080)) == EHCI_PS_SUSP0x00000080) {
1033 EOWRITE4(sc, EHCI_PORTSC(i), cmd | EHCI_PS_FPR)(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+((0x40+4*(i)))), ((cmd | 0x00000040))))
;
1034 hcr = 1;
1035 }
1036 }
1037
1038 if (hcr) {
1039 usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT50);
1040 for (i = 1; i <= sc->sc_noport; i++) {
1041 cmd = EOREAD4(sc, EHCI_PORTSC(i))(((sc)->iot)->read_4(((sc)->ioh), ((sc)->sc_offs+
((0x40+4*(i))))))
;
1042 if ((cmd & (EHCI_PS_PO0x00002000|EHCI_PS_SUSP0x00000080)) ==
1043 EHCI_PS_SUSP0x00000080)
1044 EOWRITE4(sc, EHCI_PORTSC(i),(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+((0x40+4*(i)))), ((cmd & ~0x00000040))))
1045 cmd & ~EHCI_PS_FPR)(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+((0x40+4*(i)))), ((cmd & ~0x00000040))))
;
1046 }
1047 }
1048
1049 /* Turn on controller */
1050 EOWRITE4(sc, EHCI_USBCMD,(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(0x00)), ((0x00020000 | ((((sc)->iot)->read_4(((sc)->
ioh), ((sc)->sc_offs+(0x00)))) & 0x0000000c) | 0x00000020
| 0x00000010 | 0x00000001))))
1051 EHCI_CMD_ITC_2 | /* 2 microframes interrupt delay */(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(0x00)), ((0x00020000 | ((((sc)->iot)->read_4(((sc)->
ioh), ((sc)->sc_offs+(0x00)))) & 0x0000000c) | 0x00000020
| 0x00000010 | 0x00000001))))
1052 (EOREAD4(sc, EHCI_USBCMD) & EHCI_CMD_FLS_M) |(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(0x00)), ((0x00020000 | ((((sc)->iot)->read_4(((sc)->
ioh), ((sc)->sc_offs+(0x00)))) & 0x0000000c) | 0x00000020
| 0x00000010 | 0x00000001))))
1053 EHCI_CMD_ASE |(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(0x00)), ((0x00020000 | ((((sc)->iot)->read_4(((sc)->
ioh), ((sc)->sc_offs+(0x00)))) & 0x0000000c) | 0x00000020
| 0x00000010 | 0x00000001))))
1054 EHCI_CMD_PSE |(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(0x00)), ((0x00020000 | ((((sc)->iot)->read_4(((sc)->
ioh), ((sc)->sc_offs+(0x00)))) & 0x0000000c) | 0x00000020
| 0x00000010 | 0x00000001))))
1055 EHCI_CMD_RS)(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(0x00)), ((0x00020000 | ((((sc)->iot)->read_4(((sc)->
ioh), ((sc)->sc_offs+(0x00)))) & 0x0000000c) | 0x00000020
| 0x00000010 | 0x00000001))))
;
1056
1057 /* Take over port ownership */
1058 EOWRITE4(sc, EHCI_CONFIGFLAG, EHCI_CONF_CF)(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(0x40)), ((0x00000001))))
;
1059 for (i = 0; i < 100; i++) {
1060 usb_delay_ms(&sc->sc_bus, 1);
1061 hcr = EOREAD4(sc, EHCI_USBSTS)(((sc)->iot)->read_4(((sc)->ioh), ((sc)->sc_offs+
(0x04))))
& EHCI_STS_HCH0x00001000;
1062 if (!hcr)
1063 break;
1064 }
1065
1066 if (hcr) {
1067 printf("%s: run timeout\n", sc->sc_bus.bdev.dv_xname);
1068 /* XXX should we bail here? */
1069 }
1070
1071 EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs)(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(0x08)), ((sc->sc_eintrs))))
;
1072
1073 usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT50);
1074
1075 sc->sc_bus.use_polling--;
1076 rv = config_activate_children(self, act);
1077 break;
1078 case DVACT_POWERDOWN6:
1079 rv = config_activate_children(self, act);
1080 ehci_reset(sc);
1081 break;
1082 default:
1083 rv = config_activate_children(self, act);
1084 break;
1085 }
1086 return (rv);
1087}
1088
1089usbd_status
1090ehci_reset(struct ehci_softc *sc)
1091{
1092 u_int32_t hcr, usbmode;
1093 int i;
1094
1095 EOWRITE4(sc, EHCI_USBCMD, 0)(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(0x00)), ((0))))
; /* Halt controller */
1096 for (i = 0; i < 100; i++) {
1097 usb_delay_ms(&sc->sc_bus, 1);
1098 hcr = EOREAD4(sc, EHCI_USBSTS)(((sc)->iot)->read_4(((sc)->ioh), ((sc)->sc_offs+
(0x04))))
& EHCI_STS_HCH0x00001000;
1099 if (hcr)
1100 break;
1101 }
1102
1103 if (!hcr)
1104 printf("%s: halt timeout\n", sc->sc_bus.bdev.dv_xname);
1105
1106 if (sc->sc_flags & EHCIF_USBMODE0x04)
1107 usbmode = EOREAD4(sc, EHCI_USBMODE)(((sc)->iot)->read_4(((sc)->ioh), ((sc)->sc_offs+
(0x68))))
;
1108
1109 EOWRITE4(sc, EHCI_USBCMD, EHCI_CMD_HCRESET)(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(0x00)), ((0x00000002))))
;
1110 for (i = 0; i < 100; i++) {
1111 usb_delay_ms(&sc->sc_bus, 1);
1112 hcr = EOREAD4(sc, EHCI_USBCMD)(((sc)->iot)->read_4(((sc)->ioh), ((sc)->sc_offs+
(0x00))))
& EHCI_CMD_HCRESET0x00000002;
1113 if (!hcr)
1114 break;
1115 }
1116
1117 if (hcr) {
1118 printf("%s: reset timeout\n", sc->sc_bus.bdev.dv_xname);
1119 return (USBD_IOERROR);
1120 }
1121
1122 if (sc->sc_flags & EHCIF_USBMODE0x04)
1123 EOWRITE4(sc, EHCI_USBMODE, usbmode)(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(0x68)), ((usbmode))))
;
1124
1125 return (USBD_NORMAL_COMPLETION);
1126}
1127
1128struct usbd_xfer *
1129ehci_allocx(struct usbd_bus *bus)
1130{
1131 struct ehci_xfer *ex;
1132
1133 ex = pool_get(ehcixfer, PR_NOWAIT0x0002 | PR_ZERO0x0008);
1134#ifdef DIAGNOSTIC1
1135 if (ex != NULL((void *)0))
1136 ex->isdone = 1;
1137#endif
1138 return ((struct usbd_xfer *)ex);
1139}
1140
1141void
1142ehci_freex(struct usbd_bus *bus, struct usbd_xfer *xfer)
1143{
1144 struct ehci_xfer *ex = (struct ehci_xfer*)xfer;
1145
1146#ifdef DIAGNOSTIC1
1147 if (!ex->isdone) {
1148 printf("%s: !isdone\n", __func__);
1149 return;
1150 }
1151#endif
1152 pool_put(ehcixfer, ex);
1153}
1154
1155void
1156ehci_device_clear_toggle(struct usbd_pipe *pipe)
1157{
1158 struct ehci_pipe *epipe = (struct ehci_pipe *)pipe;
1159
1160#ifdef DIAGNOSTIC1
1161 if ((epipe->sqh->qh.qh_qtd.qtd_status & htole32(EHCI_QTD_ACTIVE)((__uint32_t)(0x80))) != 0)
1162 printf("%s: queue active\n", __func__);
1163#endif
1164 epipe->sqh->qh.qh_qtd.qtd_status &= htole32(~EHCI_QTD_TOGGLE_MASK)((__uint32_t)(~0x80000000));
1165}
1166
1167#ifdef EHCI_DEBUG
1168void
1169ehci_dump_regs(struct ehci_softc *sc)
1170{
1171 int i;
1172
1173 printf("cmd=0x%08x, sts=0x%08x, ien=0x%08x\n",
1174 EOREAD4(sc, EHCI_USBCMD)(((sc)->iot)->read_4(((sc)->ioh), ((sc)->sc_offs+
(0x00))))
,
1175 EOREAD4(sc, EHCI_USBSTS)(((sc)->iot)->read_4(((sc)->ioh), ((sc)->sc_offs+
(0x04))))
,
1176 EOREAD4(sc, EHCI_USBINTR)(((sc)->iot)->read_4(((sc)->ioh), ((sc)->sc_offs+
(0x08))))
);
1177 printf("frindex=0x%08x ctrdsegm=0x%08x periodic=0x%08x async=0x%08x\n",
1178 EOREAD4(sc, EHCI_FRINDEX)(((sc)->iot)->read_4(((sc)->ioh), ((sc)->sc_offs+
(0x0c))))
,
1179 EOREAD4(sc, EHCI_CTRLDSSEGMENT)(((sc)->iot)->read_4(((sc)->ioh), ((sc)->sc_offs+
(0x10))))
,
1180 EOREAD4(sc, EHCI_PERIODICLISTBASE)(((sc)->iot)->read_4(((sc)->ioh), ((sc)->sc_offs+
(0x14))))
,
1181 EOREAD4(sc, EHCI_ASYNCLISTADDR)(((sc)->iot)->read_4(((sc)->ioh), ((sc)->sc_offs+
(0x18))))
);
1182 for (i = 1; i <= sc->sc_noport; i++)
1183 printf("port %d status=0x%08x\n", i,
1184 EOREAD4(sc, EHCI_PORTSC(i))(((sc)->iot)->read_4(((sc)->ioh), ((sc)->sc_offs+
((0x40+4*(i))))))
);
1185}
1186
1187/*
1188 * Unused function - this is meant to be called from a kernel
1189 * debugger.
1190 */
1191void
1192ehci_dump(void)
1193{
1194 ehci_dump_regs(theehci);
1195}
1196
1197void
1198ehci_dump_link(ehci_link_t link, int type)
1199{
1200 link = letoh32(link)((__uint32_t)(link));
1201 printf("0x%08x", link);
1202 if (link & EHCI_LINK_TERMINATE0x00000001)
1203 printf("<T>");
1204 else {
1205 printf("<");
1206 if (type) {
1207 switch (EHCI_LINK_TYPE(link)((link) & 0x00000006)) {
1208 case EHCI_LINK_ITD0x0:
1209 printf("ITD");
1210 break;
1211 case EHCI_LINK_QH0x2:
1212 printf("QH");
1213 break;
1214 case EHCI_LINK_SITD0x4:
1215 printf("SITD");
1216 break;
1217 case EHCI_LINK_FSTN0x6:
1218 printf("FSTN");
1219 break;
1220 }
1221 }
1222 printf(">");
1223 }
1224}
1225
1226void
1227ehci_dump_sqtds(struct ehci_soft_qtd *sqtd)
1228{
1229 int i;
1230 u_int32_t stop;
1231
1232 stop = 0;
1233 for (i = 0; sqtd && i < 20 && !stop; sqtd = sqtd->nextqtd, i++) {
1234 ehci_dump_sqtd(sqtd);
1235 usb_syncmem(&sqtd->dma,
1236 sqtd->offs + offsetof(struct ehci_qtd, qtd_next)__builtin_offsetof(struct ehci_qtd, qtd_next),
1237 sizeof(sqtd->qtd),
1238 BUS_DMASYNC_POSTWRITE0x08 | BUS_DMASYNC_POSTREAD0x02);
1239 stop = sqtd->qtd.qtd_next & htole32(EHCI_LINK_TERMINATE)((__uint32_t)(0x00000001));
1240 usb_syncmem(&sqtd->dma,
1241 sqtd->offs + offsetof(struct ehci_qtd, qtd_next)__builtin_offsetof(struct ehci_qtd, qtd_next),
1242 sizeof(sqtd->qtd), BUS_DMASYNC_PREREAD0x01);
1243 }
1244 if (!stop)
1245 printf("dump aborted, too many TDs\n");
1246}
1247
1248void
1249ehci_dump_sqtd(struct ehci_soft_qtd *sqtd)
1250{
1251 usb_syncmem(&sqtd->dma, sqtd->offs,
1252 sizeof(sqtd->qtd), BUS_DMASYNC_POSTWRITE0x08 | BUS_DMASYNC_POSTREAD0x02);
1253 printf("QTD(%p) at 0x%08x:\n", sqtd, sqtd->physaddr);
1254 ehci_dump_qtd(&sqtd->qtd);
1255 usb_syncmem(&sqtd->dma, sqtd->offs,
1256 sizeof(sqtd->qtd), BUS_DMASYNC_PREREAD0x01);
1257}
1258
1259void
1260ehci_dump_qtd(struct ehci_qtd *qtd)
1261{
1262 u_int32_t s;
1263 char sbuf[128];
1264
1265 printf(" next="); ehci_dump_link(qtd->qtd_next, 0);
1266 printf(" altnext="); ehci_dump_link(qtd->qtd_altnext, 0);
1267 printf("\n");
1268 s = letoh32(qtd->qtd_status)((__uint32_t)(qtd->qtd_status));
1269 bitmask_snprintf(EHCI_QTD_GET_STATUS(s)(((s) >> 0) & 0xff), "\20\10ACTIVE\7HALTED"
1270 "\6BUFERR\5BABBLE\4XACTERR\3MISSED\2SPLIT\1PING",
1271 sbuf, sizeof(sbuf));
1272 printf(" status=0x%08x: toggle=%d bytes=0x%x ioc=%d c_page=0x%x\n",
1273 s, EHCI_QTD_GET_TOGGLE(s)(((s) >> 31) & 0x1), EHCI_QTD_GET_BYTES(s)(((s) >> 16) & 0x7fff),
1274 EHCI_QTD_GET_IOC(s)(((s) >> 15) & 0x1), EHCI_QTD_GET_C_PAGE(s)(((s) >> 12) & 0x7));
1275 printf(" cerr=%d pid=%d stat=0x%s\n", EHCI_QTD_GET_CERR(s)(((s) >> 10) & 0x3),
1276 EHCI_QTD_GET_PID(s)(((s) >> 8) & 0x3), sbuf);
1277 for (s = 0; s < 5; s++)
1278 printf(" buffer[%d]=0x%08x\n", s, letoh32(qtd->qtd_buffer[s])((__uint32_t)(qtd->qtd_buffer[s])));
1279}
1280
1281void
1282ehci_dump_sqh(struct ehci_soft_qh *sqh)
1283{
1284 struct ehci_qh *qh = &sqh->qh;
1285 u_int32_t endp, endphub;
1286
1287 usb_syncmem(&sqh->dma, sqh->offs,
1288 sizeof(sqh->qh), BUS_DMASYNC_POSTWRITE0x08 | BUS_DMASYNC_POSTREAD0x02);
1289 printf("QH(%p) at 0x%08x:\n", sqh, sqh->physaddr);
1290 printf(" link="); ehci_dump_link(qh->qh_link, 1); printf("\n");
1291 endp = letoh32(qh->qh_endp)((__uint32_t)(qh->qh_endp));
1292 printf(" endp=0x%08x\n", endp);
1293 printf(" addr=0x%02x inact=%d endpt=%d eps=%d dtc=%d hrecl=%d\n",
1294 EHCI_QH_GET_ADDR(endp)(((endp) >> 0) & 0x7f), EHCI_QH_GET_INACT(endp)(((endp) >> 7) & 0x01),
1295 EHCI_QH_GET_ENDPT(endp)(((endp) >> 8) & 0x0f), EHCI_QH_GET_EPS(endp)(((endp) >> 12) & 0x03),
1296 EHCI_QH_GET_DTC(endp)(((endp) >> 14) & 0x01), EHCI_QH_GET_HRECL(endp)(((endp) >> 15) & 0x01));
1297 printf(" mpl=0x%x ctl=%d nrl=%d\n",
1298 EHCI_QH_GET_MPL(endp)(((endp) >> 16) & 0x7ff), EHCI_QH_GET_CTL(endp)(((endp) >> 27) & 0x01),
1299 EHCI_QH_GET_NRL(endp)(((endp) >> 28) & 0x0f));
1300 endphub = letoh32(qh->qh_endphub)((__uint32_t)(qh->qh_endphub));
1301 printf(" endphub=0x%08x\n", endphub);
1302 printf(" smask=0x%02x cmask=0x%02x huba=0x%02x port=%d mult=%d\n",
1303 EHCI_QH_GET_SMASK(endphub)(((endphub) >> 0) & 0xff), EHCI_QH_GET_CMASK(endphub)(((endphub) >> 8) & 0xff),
1304 EHCI_QH_GET_HUBA(endphub)(((endphub) >> 16) & 0x7f), EHCI_QH_GET_PORT(endphub)(((endphub) >> 23) & 0x7f),
1305 EHCI_QH_GET_MULT(endphub)(((endphub) >> 30) & 0x03));
1306 printf(" curqtd="); ehci_dump_link(qh->qh_curqtd, 0); printf("\n");
1307 printf("Overlay qTD:\n");
1308 ehci_dump_qtd(&qh->qh_qtd);
1309 usb_syncmem(&sqh->dma, sqh->offs,
1310 sizeof(sqh->qh), BUS_DMASYNC_PREREAD0x01);
1311}
1312
1313#if notyet
1314void
1315ehci_dump_itd(struct ehci_soft_itd *itd)
1316{
1317 ehci_isoc_trans_t t;
1318 ehci_isoc_bufr_ptr_t b, b2, b3;
1319 int i;
1320
1321 printf("ITD: next phys=%X\n", itd->itd.itd_next);
1322
1323 for (i = 0; i < 8; i++) {
1324 t = letoh32(itd->itd.itd_ctl[i])((__uint32_t)(itd->itd.itd_ctl[i]));
1325 printf("ITDctl %d: stat=%X len=%X ioc=%X pg=%X offs=%X\n", i,
1326 EHCI_ITD_GET_STATUS(t)(((t) >> 28) & 0xf), EHCI_ITD_GET_LEN(t)(((t) >> 16) & 0xfff),
1327 EHCI_ITD_GET_IOC(t)(((t) >> 15) & 1), EHCI_ITD_GET_PG(t)(((t) >> 12) & 0x7),
1328 EHCI_ITD_GET_OFFS(t)(((t) >> 0) & 0xfff));
1329 }
1330 printf("ITDbufr: ");
1331 for (i = 0; i < 7; i++)
1332 printf("%X,", EHCI_ITD_GET_BPTR(letoh32(itd->itd.itd_bufr[i])((__uint32_t)(itd->itd.itd_bufr[i]))));
1333
1334 b = letoh32(itd->itd.itd_bufr[0])((__uint32_t)(itd->itd.itd_bufr[0]));
1335 b2 = letoh32(itd->itd.itd_bufr[1])((__uint32_t)(itd->itd.itd_bufr[1]));
1336 b3 = letoh32(itd->itd.itd_bufr[2])((__uint32_t)(itd->itd.itd_bufr[2]));
1337 printf("\nep=%X daddr=%X dir=%d maxpkt=%X multi=%X\n",
1338 EHCI_ITD_GET_EP(b), EHCI_ITD_GET_DADDR(b)((b) & 0x7f), EHCI_ITD_GET_DIR(b2)(((b2) >> 11) & 1),
1339 EHCI_ITD_GET_MAXPKT(b2)((b2) & 0x7ff), EHCI_ITD_GET_MULTI(b3)((b3) & 0x3));
1340}
1341#endif
1342
1343#ifdef DIAGNOSTIC1
1344void
1345ehci_dump_exfer(struct ehci_xfer *ex)
1346{
1347 printf("ehci_dump_exfer: ex=%p sqtdstart=%p end=%p itdstart=%p end=%p "
1348 "isdone=%d\n", ex, ex->sqtdstart_TD.sqtd.start, ex->sqtdend_TD.sqtd.end, ex->itdstart_TD.itd.start,
1349 ex->itdend_TD.itd.end, ex->isdone);
1350}
1351#endif
1352
1353#endif /* EHCI_DEBUG */
1354
1355usbd_status
1356ehci_open(struct usbd_pipe *pipe)
1357{
1358 struct usbd_device *dev = pipe->device;
1359 struct ehci_softc *sc = (struct ehci_softc *)dev->bus;
1360 usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc;
1361 u_int8_t addr = dev->address;
1362 u_int8_t xfertype = UE_GET_XFERTYPE(ed->bmAttributes)((ed->bmAttributes) & 0x03);
1363 struct ehci_pipe *epipe = (struct ehci_pipe *)pipe;
1364 struct ehci_soft_qh *sqh;
1365 usbd_status err;
1366 int s;
1367 int ival, speed, naks;
1368 int hshubaddr, hshubport;
1369
1370 DPRINTFN(1, ("ehci_open: pipe=%p, addr=%d, endpt=%d\n",
1371 pipe, addr, ed->bEndpointAddress));
1372
1373 if (sc->sc_bus.dying)
1374 return (USBD_IOERROR);
1375
1376 if (dev->myhsport) {
1377 hshubaddr = dev->myhsport->parent->address;
1378 hshubport = dev->myhsport->portno;
1379 } else {
1380 hshubaddr = 0;
1381 hshubport = 0;
1382 }
1383
1384 /* Root Hub */
1385 if (pipe->device->depth == 0) {
1386 switch (ed->bEndpointAddress) {
1387 case USB_CONTROL_ENDPOINT0:
1388 pipe->methods = &ehci_root_ctrl_methods;
1389 break;
1390 case UE_DIR_IN0x80 | EHCI_INTR_ENDPT1:
1391 pipe->methods = &ehci_root_intr_methods;
1392 break;
1393 default:
1394 return (USBD_INVAL);
1395 }
1396 return (USBD_NORMAL_COMPLETION);
1397 }
1398
1399 /* XXX All this stuff is only valid for async. */
1400 switch (dev->speed) {
1401 case USB_SPEED_LOW1:
1402 speed = EHCI_QH_SPEED_LOW0x1;
1403 break;
1404 case USB_SPEED_FULL2:
1405 speed = EHCI_QH_SPEED_FULL0x0;
1406 break;
1407 case USB_SPEED_HIGH3:
1408 speed = EHCI_QH_SPEED_HIGH0x2;
1409 break;
1410 default:
1411 panic("ehci_open: bad device speed %d", dev->speed);
1412 }
1413
1414 /*
1415 * NAK reload count:
1416 * must be zero with using periodic transfer.
1417 * Linux 4.20's driver (ehci-q.c) sets 4, we use same value.
1418 */
1419 naks = ((xfertype == UE_CONTROL0x00) || (xfertype == UE_BULK0x02)) ? 4 : 0;
1420
1421 /* Allocate sqh for everything, save isoc xfers */
1422 if (xfertype != UE_ISOCHRONOUS0x01) {
1423 sqh = ehci_alloc_sqh(sc);
1424 if (sqh == NULL((void *)0))
1425 return (USBD_NOMEM);
1426 /* qh_link filled when the QH is added */
1427 sqh->qh.qh_endp = htole32(((__uint32_t)((addr) | ((((ed->bEndpointAddress) & 0x0f
)) << 8) | ((speed) << 12) | (xfertype == 0x00 ? 0x00004000
: 0) | (((*(u_int16_t *)(ed->wMaxPacketSize))) << 16
) | (speed != 0x2 && xfertype == 0x00 ? 0x08000000 : 0
) | ((naks) << 28)))
1428 EHCI_QH_SET_ADDR(addr) |((__uint32_t)((addr) | ((((ed->bEndpointAddress) & 0x0f
)) << 8) | ((speed) << 12) | (xfertype == 0x00 ? 0x00004000
: 0) | (((*(u_int16_t *)(ed->wMaxPacketSize))) << 16
) | (speed != 0x2 && xfertype == 0x00 ? 0x08000000 : 0
) | ((naks) << 28)))
1429 EHCI_QH_SET_ENDPT(UE_GET_ADDR(ed->bEndpointAddress)) |((__uint32_t)((addr) | ((((ed->bEndpointAddress) & 0x0f
)) << 8) | ((speed) << 12) | (xfertype == 0x00 ? 0x00004000
: 0) | (((*(u_int16_t *)(ed->wMaxPacketSize))) << 16
) | (speed != 0x2 && xfertype == 0x00 ? 0x08000000 : 0
) | ((naks) << 28)))
1430 EHCI_QH_SET_EPS(speed) |((__uint32_t)((addr) | ((((ed->bEndpointAddress) & 0x0f
)) << 8) | ((speed) << 12) | (xfertype == 0x00 ? 0x00004000
: 0) | (((*(u_int16_t *)(ed->wMaxPacketSize))) << 16
) | (speed != 0x2 && xfertype == 0x00 ? 0x08000000 : 0
) | ((naks) << 28)))
1431 (xfertype == UE_CONTROL ? EHCI_QH_DTC : 0) |((__uint32_t)((addr) | ((((ed->bEndpointAddress) & 0x0f
)) << 8) | ((speed) << 12) | (xfertype == 0x00 ? 0x00004000
: 0) | (((*(u_int16_t *)(ed->wMaxPacketSize))) << 16
) | (speed != 0x2 && xfertype == 0x00 ? 0x08000000 : 0
) | ((naks) << 28)))
1432 EHCI_QH_SET_MPL(UGETW(ed->wMaxPacketSize)) |((__uint32_t)((addr) | ((((ed->bEndpointAddress) & 0x0f
)) << 8) | ((speed) << 12) | (xfertype == 0x00 ? 0x00004000
: 0) | (((*(u_int16_t *)(ed->wMaxPacketSize))) << 16
) | (speed != 0x2 && xfertype == 0x00 ? 0x08000000 : 0
) | ((naks) << 28)))
1433 (speed != EHCI_QH_SPEED_HIGH && xfertype == UE_CONTROL ?((__uint32_t)((addr) | ((((ed->bEndpointAddress) & 0x0f
)) << 8) | ((speed) << 12) | (xfertype == 0x00 ? 0x00004000
: 0) | (((*(u_int16_t *)(ed->wMaxPacketSize))) << 16
) | (speed != 0x2 && xfertype == 0x00 ? 0x08000000 : 0
) | ((naks) << 28)))
1434 EHCI_QH_CTL : 0) |((__uint32_t)((addr) | ((((ed->bEndpointAddress) & 0x0f
)) << 8) | ((speed) << 12) | (xfertype == 0x00 ? 0x00004000
: 0) | (((*(u_int16_t *)(ed->wMaxPacketSize))) << 16
) | (speed != 0x2 && xfertype == 0x00 ? 0x08000000 : 0
) | ((naks) << 28)))
1435 EHCI_QH_SET_NRL(naks)((__uint32_t)((addr) | ((((ed->bEndpointAddress) & 0x0f
)) << 8) | ((speed) << 12) | (xfertype == 0x00 ? 0x00004000
: 0) | (((*(u_int16_t *)(ed->wMaxPacketSize))) << 16
) | (speed != 0x2 && xfertype == 0x00 ? 0x08000000 : 0
) | ((naks) << 28)))
1436 )((__uint32_t)((addr) | ((((ed->bEndpointAddress) & 0x0f
)) << 8) | ((speed) << 12) | (xfertype == 0x00 ? 0x00004000
: 0) | (((*(u_int16_t *)(ed->wMaxPacketSize))) << 16
) | (speed != 0x2 && xfertype == 0x00 ? 0x08000000 : 0
) | ((naks) << 28)))
;
1437 /*
1438 * To reduce conflict with split isochronous transfer,
1439 * schedule (split) interrupt transfer at latter half of
1440 * 1ms frame:
1441 *
1442 * |<-------------- H-Frame -------------->|
1443 * .H0 :H1 H2 H3 H4 H5 H6 H7 .H0" :H1"
1444 * . : . :
1445 * [HS] . : SS CS CS' CS" . :
1446 * [FS/LS] . : |<== >>>> >>>| . :
1447 * . : . :
1448 * .B7' :B0 B1 B2 B3 B4 B5 B6 .B7 :B0"
1449 * |<-------------- B-Frame -------------->|
1450 *
1451 */
1452 sqh->qh.qh_endphub = htole32(((__uint32_t)(((1) << 30) | ((xfertype == 0x03 ? 0x08 :
0) << 0)))
1453 EHCI_QH_SET_MULT(1) |((__uint32_t)(((1) << 30) | ((xfertype == 0x03 ? 0x08 :
0) << 0)))
1454 EHCI_QH_SET_SMASK(xfertype == UE_INTERRUPT ? 0x08 : 0)((__uint32_t)(((1) << 30) | ((xfertype == 0x03 ? 0x08 :
0) << 0)))
1455 )((__uint32_t)(((1) << 30) | ((xfertype == 0x03 ? 0x08 :
0) << 0)))
;
1456 if (speed != EHCI_QH_SPEED_HIGH0x2) {
1457 sqh->qh.qh_endphub |= htole32(((__uint32_t)(((hshubaddr) << 16) | ((hshubport) <<
23) | ((0xe0) << 8)))
1458 EHCI_QH_SET_HUBA(hshubaddr) |((__uint32_t)(((hshubaddr) << 16) | ((hshubport) <<
23) | ((0xe0) << 8)))
1459 EHCI_QH_SET_PORT(hshubport) |((__uint32_t)(((hshubaddr) << 16) | ((hshubport) <<
23) | ((0xe0) << 8)))
1460 EHCI_QH_SET_CMASK(0xe0)((__uint32_t)(((hshubaddr) << 16) | ((hshubport) <<
23) | ((0xe0) << 8)))
1461 )((__uint32_t)(((hshubaddr) << 16) | ((hshubport) <<
23) | ((0xe0) << 8)))
;
1462 }
1463 sqh->qh.qh_curqtd = htole32(EHCI_LINK_TERMINATE)((__uint32_t)(0x00000001));
1464 /* Fill the overlay qTD */
1465 sqh->qh.qh_qtd.qtd_next = htole32(EHCI_LINK_TERMINATE)((__uint32_t)(0x00000001));
1466 sqh->qh.qh_qtd.qtd_altnext = htole32(EHCI_LINK_TERMINATE)((__uint32_t)(0x00000001));
1467 sqh->qh.qh_qtd.qtd_status =
1468 htole32(EHCI_QTD_SET_TOGGLE(pipe->endpoint->savedtoggle))((__uint32_t)(((pipe->endpoint->savedtoggle) << 31
)))
;
1469
1470 usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh),
1471 BUS_DMASYNC_PREWRITE0x04 | BUS_DMASYNC_PREREAD0x01);
1472 epipe->sqh = sqh;
1473 } /*xfertype == UE_ISOC*/
1474
1475 switch (xfertype) {
1476 case UE_CONTROL0x00:
1477 err = usb_allocmem(&sc->sc_bus, sizeof(usb_device_request_t),
1478 0, USB_DMA_COHERENT(1 << 0), &epipe->u.ctl.reqdma);
1479 if (err) {
1480 ehci_free_sqh(sc, sqh);
1481 return (err);
1482 }
1483 pipe->methods = &ehci_device_ctrl_methods;
1484 s = splusb()splraise(0x5);
1485 ehci_add_qh(sqh, sc->sc_async_head);
1486 splx(s)spllower(s);
1487 break;
1488 case UE_BULK0x02:
1489 pipe->methods = &ehci_device_bulk_methods;
1490 s = splusb()splraise(0x5);
1491 ehci_add_qh(sqh, sc->sc_async_head);
1492 splx(s)spllower(s);
1493 break;
1494 case UE_INTERRUPT0x03:
1495 pipe->methods = &ehci_device_intr_methods;
1496 ival = pipe->interval;
1497 if (ival == USBD_DEFAULT_INTERVAL(-1))
1498 ival = ed->bInterval;
1499 s = splusb()splraise(0x5);
1500 err = ehci_device_setintr(sc, sqh, ival);
1501 splx(s)spllower(s);
1502 return (err);
1503 case UE_ISOCHRONOUS0x01:
1504 switch (speed) {
1505 case EHCI_QH_SPEED_HIGH0x2:
1506 case EHCI_QH_SPEED_FULL0x0:
1507 pipe->methods = &ehci_device_isoc_methods;
1508 break;
1509 case EHCI_QH_SPEED_LOW0x1:
1510 default:
1511 return (USBD_INVAL);
1512 }
1513 /* Spec page 271 says intervals > 16 are invalid */
1514 if (ed->bInterval == 0 || ed->bInterval > 16) {
1515 printf("ehci: opening pipe with invalid bInterval\n");
1516 return (USBD_INVAL);
1517 }
1518 if (UGETW(ed->wMaxPacketSize)(*(u_int16_t *)(ed->wMaxPacketSize)) == 0) {
1519 printf("ehci: zero length endpoint open request\n");
1520 return (USBD_INVAL);
1521 }
1522 epipe->u.isoc.next_frame = 0;
1523 epipe->u.isoc.cur_xfers = 0;
1524 break;
1525 default:
1526 DPRINTF(("ehci: bad xfer type %d\n", xfertype));
1527 return (USBD_INVAL);
1528 }
1529 return (USBD_NORMAL_COMPLETION);
1530}
1531
1532/*
1533 * Add an ED to the schedule. Called at splusb().
1534 * If in the async schedule, it will always have a next.
1535 * If in the intr schedule it may not.
1536 */
1537void
1538ehci_add_qh(struct ehci_soft_qh *sqh, struct ehci_soft_qh *head)
1539{
1540 splsoftassert(IPL_SOFTUSB)do { if (splassert_ctl > 0) { splassert_check(0x5, __func__
); } } while (0)
;
1541
1542 usb_syncmem(&head->dma, head->offs + offsetof(struct ehci_qh, qh_link)__builtin_offsetof(struct ehci_qh, qh_link),
1543 sizeof(head->qh.qh_link), BUS_DMASYNC_POSTWRITE0x08);
1544 sqh->next = head->next;
1545 sqh->prev = head;
1546 sqh->qh.qh_link = head->qh.qh_link;
1547 usb_syncmem(&sqh->dma, sqh->offs + offsetof(struct ehci_qh, qh_link)__builtin_offsetof(struct ehci_qh, qh_link),
1548 sizeof(sqh->qh.qh_link), BUS_DMASYNC_PREWRITE0x04);
1549 head->next = sqh;
1550 if (sqh->next)
1551 sqh->next->prev = sqh;
1552 head->qh.qh_link = htole32(sqh->physaddr | EHCI_LINK_QH)((__uint32_t)(sqh->physaddr | 0x2));
1553 usb_syncmem(&head->dma, head->offs + offsetof(struct ehci_qh, qh_link)__builtin_offsetof(struct ehci_qh, qh_link),
1554 sizeof(head->qh.qh_link), BUS_DMASYNC_PREWRITE0x04);
1555}
1556
1557/*
1558 * Remove an ED from the schedule. Called at splusb().
1559 * Will always have a 'next' if it's in the async list as it's circular.
1560 */
1561void
1562ehci_rem_qh(struct ehci_softc *sc, struct ehci_soft_qh *sqh)
1563{
1564 splsoftassert(IPL_SOFTUSB)do { if (splassert_ctl > 0) { splassert_check(0x5, __func__
); } } while (0)
;
1565 /* XXX */
1566 usb_syncmem(&sqh->dma, sqh->offs + offsetof(struct ehci_qh, qh_link)__builtin_offsetof(struct ehci_qh, qh_link),
1567 sizeof(sqh->qh.qh_link), BUS_DMASYNC_POSTWRITE0x08);
1568 sqh->prev->qh.qh_link = sqh->qh.qh_link;
1569 sqh->prev->next = sqh->next;
1570 if (sqh->next)
1571 sqh->next->prev = sqh->prev;
1572 usb_syncmem(&sqh->prev->dma,
1573 sqh->prev->offs + offsetof(struct ehci_qh, qh_link)__builtin_offsetof(struct ehci_qh, qh_link),
1574 sizeof(sqh->prev->qh.qh_link), BUS_DMASYNC_PREWRITE0x04);
1575
1576 ehci_sync_hc(sc);
1577}
1578
1579void
1580ehci_set_qh_qtd(struct ehci_soft_qh *sqh, struct ehci_soft_qtd *sqtd)
1581{
1582 int i;
1583 u_int32_t status;
1584
1585 /* Save toggle bit and ping status. */
1586 usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh),
1587 BUS_DMASYNC_POSTWRITE0x08 | BUS_DMASYNC_POSTREAD0x02);
1588 status = sqh->qh.qh_qtd.qtd_status &
1589 htole32(EHCI_QTD_TOGGLE_MASK |((__uint32_t)(0x80000000 | ((0x01) << 0)))
1590 EHCI_QTD_SET_STATUS(EHCI_QTD_PINGSTATE))((__uint32_t)(0x80000000 | ((0x01) << 0)));
1591 /* Set HALTED to make hw leave it alone. */
1592 sqh->qh.qh_qtd.qtd_status =
1593 htole32(EHCI_QTD_SET_STATUS(EHCI_QTD_HALTED))((__uint32_t)(((0x40) << 0)));
1594 usb_syncmem(&sqh->dma,
1595 sqh->offs + offsetof(struct ehci_qh, qh_qtd.qtd_status)__builtin_offsetof(struct ehci_qh, qh_qtd.qtd_status),
1596 sizeof(sqh->qh.qh_qtd.qtd_status),
1597 BUS_DMASYNC_PREWRITE0x04 | BUS_DMASYNC_PREREAD0x01);
1598 sqh->qh.qh_curqtd = 0;
1599 sqh->qh.qh_qtd.qtd_next = htole32(sqtd->physaddr)((__uint32_t)(sqtd->physaddr));
1600 sqh->qh.qh_qtd.qtd_altnext = htole32(EHCI_LINK_TERMINATE)((__uint32_t)(0x00000001));
1601 for (i = 0; i < EHCI_QTD_NBUFFERS5; i++)
1602 sqh->qh.qh_qtd.qtd_buffer[i] = 0;
1603 sqh->sqtd = sqtd;
1604 usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh),
1605 BUS_DMASYNC_PREWRITE0x04 | BUS_DMASYNC_PREREAD0x01);
1606 /* Set !HALTED && !ACTIVE to start execution, preserve some fields */
1607 sqh->qh.qh_qtd.qtd_status = status;
1608 usb_syncmem(&sqh->dma,
1609 sqh->offs + offsetof(struct ehci_qh, qh_qtd.qtd_status)__builtin_offsetof(struct ehci_qh, qh_qtd.qtd_status),
1610 sizeof(sqh->qh.qh_qtd.qtd_status),
1611 BUS_DMASYNC_PREWRITE0x04 | BUS_DMASYNC_PREREAD0x01);
1612}
1613
1614/*
1615 * Ensure that the HC has released all references to the QH. We do this
1616 * by asking for a Async Advance Doorbell interrupt and then we wait for
1617 * the interrupt.
1618 * To make this easier we first obtain exclusive use of the doorbell.
1619 */
1620void
1621ehci_sync_hc(struct ehci_softc *sc)
1622{
1623 int s, error;
1624 int tries = 0;
1625
1626 if (sc->sc_bus.dying) {
1627 return;
1628 }
1629
1630 /* get doorbell */
1631 rw_enter_write(&sc->sc_doorbell_lock);
1632 s = splhardusb()splraise(0x6);
1633 do {
1634 EOWRITE4(sc, EHCI_USBCMD, EOREAD4(sc, EHCI_USBCMD) |(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(0x00)), (((((sc)->iot)->read_4(((sc)->ioh), ((sc)->
sc_offs+(0x00)))) | 0x00000040))))
1635 EHCI_CMD_IAAD)(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(0x00)), (((((sc)->iot)->read_4(((sc)->ioh), ((sc)->
sc_offs+(0x00)))) | 0x00000040))))
;
1636 error = tsleep_nsec(&sc->sc_async_head, PZERO22, "ehcidi",
1637 MSEC_TO_NSEC(500));
1638 } while (error && ++tries < 10);
1639 splx(s)spllower(s);
1640 /* release doorbell */
1641 rw_exit_write(&sc->sc_doorbell_lock);
1642#ifdef DIAGNOSTIC1
1643 if (error)
1644 printf("ehci_sync_hc: tsleep() = %d\n", error);
1645#endif
1646}
1647
1648void
1649ehci_rem_itd_chain(struct ehci_softc *sc, struct ehci_xfer *ex)
1650{
1651 struct ehci_soft_itd *itd, *prev = NULL((void *)0);
1652
1653 splsoftassert(IPL_SOFTUSB)do { if (splassert_ctl > 0) { splassert_check(0x5, __func__
); } } while (0)
;
1654
1655 KASSERT(ex->itdstart != NULL && ex->itdend != NULL)((ex->_TD.itd.start != ((void *)0) && ex->_TD.itd
.end != ((void *)0)) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/dev/usb/ehci.c"
, 1655, "ex->itdstart != NULL && ex->itdend != NULL"
))
;
1656
1657 for (itd = ex->itdstart_TD.itd.start; itd != NULL((void *)0); itd = itd->xfer_next) {
1658 prev = itd->u.frame_list.prev;
1659 /* Unlink itd from hardware chain, or frame array */
1660 if (prev == NULL((void *)0)) { /* We're at the table head */
1661 sc->sc_softitds[itd->slot] = itd->u.frame_list.next;
1662 sc->sc_flist[itd->slot] = itd->itd.itd_next;
1663 usb_syncmem(&sc->sc_fldma,
1664 sizeof(uint32_t) * itd->slot, sizeof(uint32_t),
1665 BUS_DMASYNC_PREWRITE0x04 | BUS_DMASYNC_PREREAD0x01);
1666
1667 if (itd->u.frame_list.next != NULL((void *)0))
1668 itd->u.frame_list.next->u.frame_list.prev =
1669 NULL((void *)0);
1670 } else {
1671 /* XXX this part is untested... */
1672 prev->itd.itd_next = itd->itd.itd_next;
1673 usb_syncmem(&itd->dma,
1674 itd->offs + offsetof(struct ehci_itd, itd_next)__builtin_offsetof(struct ehci_itd, itd_next),
1675 sizeof(itd->itd.itd_next), BUS_DMASYNC_PREWRITE0x04);
1676
1677 prev->u.frame_list.next = itd->u.frame_list.next;
1678 if (itd->u.frame_list.next != NULL((void *)0))
1679 itd->u.frame_list.next->u.frame_list.prev =
1680 prev;
1681 }
1682 }
1683}
1684
1685void
1686ehci_free_itd_chain(struct ehci_softc *sc, struct ehci_xfer *ex)
1687{
1688 struct ehci_soft_itd *itd, *prev = NULL((void *)0);
1689
1690 splsoftassert(IPL_SOFTUSB)do { if (splassert_ctl > 0) { splassert_check(0x5, __func__
); } } while (0)
;
1691
1692 KASSERT(ex->itdstart != NULL && ex->itdend != NULL)((ex->_TD.itd.start != ((void *)0) && ex->_TD.itd
.end != ((void *)0)) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/dev/usb/ehci.c"
, 1692, "ex->itdstart != NULL && ex->itdend != NULL"
))
;
1693
1694 for (itd = ex->itdstart_TD.itd.start; itd != NULL((void *)0); itd = itd->xfer_next) {
1695 if (prev != NULL((void *)0))
1696 ehci_free_itd(sc, prev);
1697 prev = itd;
1698 }
1699 if (prev)
1700 ehci_free_itd(sc, prev);
1701 ex->itdstart_TD.itd.start = NULL((void *)0);
1702 ex->itdend_TD.itd.end = NULL((void *)0);
1703}
1704
1705/*
1706 * Data structures and routines to emulate the root hub.
1707 */
1708usb_device_descriptor_t ehci_devd = {
1709 USB_DEVICE_DESCRIPTOR_SIZE18,
1710 UDESC_DEVICE0x01, /* type */
1711 {0x00, 0x02}, /* USB version */
1712 UDCLASS_HUB0x09, /* class */
1713 UDSUBCLASS_HUB0x00, /* subclass */
1714 UDPROTO_HSHUBSTT0x01, /* protocol */
1715 64, /* max packet */
1716 {0},{0},{0x00,0x01}, /* device id */
1717 1,2,0, /* string indices */
1718 1 /* # of configurations */
1719};
1720
1721usb_device_qualifier_t ehci_odevd = {
1722 USB_DEVICE_DESCRIPTOR_SIZE18,
1723 UDESC_DEVICE_QUALIFIER0x06, /* type */
1724 {0x00, 0x02}, /* USB version */
1725 UDCLASS_HUB0x09, /* class */
1726 UDSUBCLASS_HUB0x00, /* subclass */
1727 UDPROTO_FSHUB0x00, /* protocol */
1728 64, /* max packet */
1729 1, /* # of configurations */
1730 0
1731};
1732
1733usb_config_descriptor_t ehci_confd = {
1734 USB_CONFIG_DESCRIPTOR_SIZE9,
1735 UDESC_CONFIG0x02,
1736 {USB_CONFIG_DESCRIPTOR_SIZE9 +
1737 USB_INTERFACE_DESCRIPTOR_SIZE9 +
1738 USB_ENDPOINT_DESCRIPTOR_SIZE7},
1739 1,
1740 1,
1741 0,
1742 UC_BUS_POWERED0x80 | UC_SELF_POWERED0x40,
1743 0 /* max power */
1744};
1745
1746usb_interface_descriptor_t ehci_ifcd = {
1747 USB_INTERFACE_DESCRIPTOR_SIZE9,
1748 UDESC_INTERFACE0x04,
1749 0,
1750 0,
1751 1,
1752 UICLASS_HUB0x09,
1753 UISUBCLASS_HUB0,
1754 UIPROTO_HSHUBSTT0,
1755 0
1756};
1757
1758usb_endpoint_descriptor_t ehci_endpd = {
1759 USB_ENDPOINT_DESCRIPTOR_SIZE7,
1760 UDESC_ENDPOINT0x05,
1761 UE_DIR_IN0x80 | EHCI_INTR_ENDPT1,
1762 UE_INTERRUPT0x03,
1763 {8, 0}, /* max packet */
1764 12
1765};
1766
1767usb_hub_descriptor_t ehci_hubd = {
1768 USB_HUB_DESCRIPTOR_SIZE8,
1769 UDESC_HUB0x29,
1770 0,
1771 {0,0},
1772 0,
1773 0,
1774 {0},
1775};
1776
1777/*
1778 * Simulate a hardware hub by handling all the necessary requests.
1779 */
1780usbd_status
1781ehci_root_ctrl_transfer(struct usbd_xfer *xfer)
1782{
1783 usbd_status err;
1784
1785 /* Insert last in queue. */
1786 err = usb_insert_transfer(xfer);
1787 if (err)
1788 return (err);
1789
1790 /* Pipe isn't running, start first */
1791 return (ehci_root_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue)((&xfer->pipe->queue)->sqh_first)));
1792}
1793
1794usbd_status
1795ehci_root_ctrl_start(struct usbd_xfer *xfer)
1796{
1797 struct ehci_softc *sc = (struct ehci_softc *)xfer->device->bus;
1798 usb_device_request_t *req;
1799 void *buf = NULL((void *)0);
1
'buf' initialized to a null pointer value
1800 int port, i;
1801 int s, len, value, index, l, totlen = 0;
1802 usb_port_status_t ps;
1803 usb_hub_descriptor_t hubd;
1804 usbd_status err;
1805 u_int32_t v;
1806
1807 if (sc->sc_bus.dying)
2
Assuming field 'dying' is 0
3
Taking false branch
1808 return (USBD_IOERROR);
1809
1810#ifdef DIAGNOSTIC1
1811 if (!(xfer->rqflags & URQ_REQUEST0x01))
4
Assuming the condition is false
5
Taking false branch
1812 /* XXX panic */
1813 return (USBD_INVAL);
1814#endif
1815 req = &xfer->request;
1816
1817 DPRINTFN(4,("ehci_root_ctrl_start: type=0x%02x request=%02x\n",
1818 req->bmRequestType, req->bRequest));
1819
1820 len = UGETW(req->wLength)(*(u_int16_t *)(req->wLength));
1821 value = UGETW(req->wValue)(*(u_int16_t *)(req->wValue));
1822 index = UGETW(req->wIndex)(*(u_int16_t *)(req->wIndex));
1823
1824 if (len != 0)
6
Assuming 'len' is equal to 0
7
Taking false branch
1825 buf = KERNADDR(&xfer->dmabuf, 0)((void *)((char *)((&xfer->dmabuf)->block->kaddr
+ (&xfer->dmabuf)->offs) + (0)))
;
1826
1827#define C(x,y)((x) | ((y) << 8)) ((x) | ((y) << 8))
1828 switch(C(req->bRequest, req->bmRequestType)((req->bRequest) | ((req->bmRequestType) << 8))) {
8
Control jumps to 'case 32774:' at line 1843
1829 case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE)((0x01) | (((0x00 | 0x00 | 0x00)) << 8)):
1830 case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE)((0x01) | (((0x00 | 0x00 | 0x01)) << 8)):
1831 case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT)((0x01) | (((0x00 | 0x00 | 0x02)) << 8)):
1832 /*
1833 * DEVICE_REMOTE_WAKEUP and ENDPOINT_HALT are no-ops
1834 * for the integrated root hub.
1835 */
1836 break;
1837 case C(UR_GET_CONFIG, UT_READ_DEVICE)((0x08) | (((0x80 | 0x00 | 0x00)) << 8)):
1838 if (len > 0) {
1839 *(u_int8_t *)buf = sc->sc_conf;
1840 totlen = 1;
1841 }
1842 break;
1843 case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE)((0x06) | (((0x80 | 0x00 | 0x00)) << 8)):
1844 DPRINTFN(8,("ehci_root_ctrl_start: wValue=0x%04x\n", value));
1845 switch(value >> 8) {
9
Control jumps to 'case 2:' at line 1868
1846 case UDESC_DEVICE0x01:
1847 if ((value & 0xff) != 0) {
1848 err = USBD_IOERROR;
1849 goto ret;
1850 }
1851 totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE18);
1852 USETW(ehci_devd.idVendor, sc->sc_id_vendor)(*(u_int16_t *)(ehci_devd.idVendor) = (sc->sc_id_vendor));
1853 memcpy(buf, &ehci_devd, l)__builtin_memcpy((buf), (&ehci_devd), (l));
1854 break;
1855 case UDESC_DEVICE_QUALIFIER0x06:
1856 if ((value & 0xff) != 0) {
1857 err = USBD_IOERROR;
1858 goto ret;
1859 }
1860 totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE18);
1861 memcpy(buf, &ehci_odevd, l)__builtin_memcpy((buf), (&ehci_odevd), (l));
1862 break;
1863 /*
1864 * We can't really operate at another speed, but the spec says
1865 * we need this descriptor.
1866 */
1867 case UDESC_OTHER_SPEED_CONFIGURATION0x07:
1868 case UDESC_CONFIG0x02:
1869 if ((value & 0xff) != 0) {
10
Assuming the condition is false
11
Taking false branch
1870 err = USBD_IOERROR;
1871 goto ret;
1872 }
1873 totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE9);
1874 memcpy(buf, &ehci_confd, l)__builtin_memcpy((buf), (&ehci_confd), (l));
1875 ((usb_config_descriptor_t *)buf)->bDescriptorType =
12
Access to field 'bDescriptorType' results in a dereference of a null pointer (loaded from variable 'buf')
1876 value >> 8;
1877 buf = (char *)buf + l;
1878 len -= l;
1879 l = min(len, USB_INTERFACE_DESCRIPTOR_SIZE9);
1880 totlen += l;
1881 memcpy(buf, &ehci_ifcd, l)__builtin_memcpy((buf), (&ehci_ifcd), (l));
1882 buf = (char *)buf + l;
1883 len -= l;
1884 l = min(len, USB_ENDPOINT_DESCRIPTOR_SIZE7);
1885 totlen += l;
1886 memcpy(buf, &ehci_endpd, l)__builtin_memcpy((buf), (&ehci_endpd), (l));
1887 break;
1888 case UDESC_STRING0x03:
1889 if (len == 0)
1890 break;
1891 *(u_int8_t *)buf = 0;
1892 totlen = 1;
1893 switch (value & 0xff) {
1894 case 0: /* Language table */
1895 totlen = usbd_str(buf, len, "\001");
1896 break;
1897 case 1: /* Vendor */
1898 totlen = usbd_str(buf, len, sc->sc_vendor);
1899 break;
1900 case 2: /* Product */
1901 totlen = usbd_str(buf, len, "EHCI root hub");
1902 break;
1903 }
1904 break;
1905 default:
1906 err = USBD_IOERROR;
1907 goto ret;
1908 }
1909 break;
1910 case C(UR_GET_INTERFACE, UT_READ_INTERFACE)((0x0a) | (((0x80 | 0x00 | 0x01)) << 8)):
1911 if (len > 0) {
1912 *(u_int8_t *)buf = 0;
1913 totlen = 1;
1914 }
1915 break;
1916 case C(UR_GET_STATUS, UT_READ_DEVICE)((0x00) | (((0x80 | 0x00 | 0x00)) << 8)):
1917 if (len > 1) {
1918 USETW(((usb_status_t *)buf)->wStatus,UDS_SELF_POWERED)(*(u_int16_t *)(((usb_status_t *)buf)->wStatus) = (0x0001)
)
;
1919 totlen = 2;
1920 }
1921 break;
1922 case C(UR_GET_STATUS, UT_READ_INTERFACE)((0x00) | (((0x80 | 0x00 | 0x01)) << 8)):
1923 case C(UR_GET_STATUS, UT_READ_ENDPOINT)((0x00) | (((0x80 | 0x00 | 0x02)) << 8)):
1924 if (len > 1) {
1925 USETW(((usb_status_t *)buf)->wStatus, 0)(*(u_int16_t *)(((usb_status_t *)buf)->wStatus) = (0));
1926 totlen = 2;
1927 }
1928 break;
1929 case C(UR_SET_ADDRESS, UT_WRITE_DEVICE)((0x05) | (((0x00 | 0x00 | 0x00)) << 8)):
1930 if (value >= USB_MAX_DEVICES128) {
1931 err = USBD_IOERROR;
1932 goto ret;
1933 }
1934 break;
1935 case C(UR_SET_CONFIG, UT_WRITE_DEVICE)((0x09) | (((0x00 | 0x00 | 0x00)) << 8)):
1936 if (value != 0 && value != 1) {
1937 err = USBD_IOERROR;
1938 goto ret;
1939 }
1940 sc->sc_conf = value;
1941 break;
1942 case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE)((0x07) | (((0x00 | 0x00 | 0x00)) << 8)):
1943 break;
1944 case C(UR_SET_FEATURE, UT_WRITE_DEVICE)((0x03) | (((0x00 | 0x00 | 0x00)) << 8)):
1945 case C(UR_SET_FEATURE, UT_WRITE_INTERFACE)((0x03) | (((0x00 | 0x00 | 0x01)) << 8)):
1946 case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT)((0x03) | (((0x00 | 0x00 | 0x02)) << 8)):
1947 err = USBD_IOERROR;
1948 goto ret;
1949 case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE)((0x0b) | (((0x00 | 0x00 | 0x01)) << 8)):
1950 break;
1951 case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT)((0x0c) | (((0x00 | 0x00 | 0x02)) << 8)):
1952 break;
1953 /* Hub requests */
1954 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE)((0x01) | (((0x00 | 0x20 | 0x00)) << 8)):
1955 break;
1956 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER)((0x01) | (((0x00 | 0x20 | 0x03)) << 8)):
1957 DPRINTFN(8, ("ehci_root_ctrl_start: UR_CLEAR_PORT_FEATURE "
1958 "port=%d feature=%d\n", index, value));
1959 if (index < 1 || index > sc->sc_noport) {
1960 err = USBD_IOERROR;
1961 goto ret;
1962 }
1963 port = EHCI_PORTSC(index)(0x40+4*(index));
1964 v = EOREAD4(sc, port)(((sc)->iot)->read_4(((sc)->ioh), ((sc)->sc_offs+
(port))))
&~ EHCI_PS_CLEAR(0x00000020|0x00000008|0x00000002);
1965 switch(value) {
1966 case UHF_PORT_ENABLE1:
1967 EOWRITE4(sc, port, v &~ EHCI_PS_PE)(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(port)), ((v &~ 0x00000004))))
;
1968 break;
1969 case UHF_PORT_SUSPEND2:
1970 EOWRITE4(sc, port, v &~ EHCI_PS_SUSP)(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(port)), ((v &~ 0x00000080))))
;
1971 break;
1972 case UHF_PORT_POWER8:
1973 EOWRITE4(sc, port, v &~ EHCI_PS_PP)(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(port)), ((v &~ 0x00001000))))
;
1974 break;
1975 case UHF_PORT_TEST21:
1976 DPRINTFN(2,("ehci_root_ctrl_start: "
1977 "clear port test %d\n", index));
1978 break;
1979 case UHF_PORT_INDICATOR22:
1980 DPRINTFN(2,("ehci_root_ctrl_start: "
1981 "clear port index %d\n", index));
1982 EOWRITE4(sc, port, v &~ EHCI_PS_PIC)(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(port)), ((v &~ 0x0000c000))))
;
1983 break;
1984 case UHF_C_PORT_CONNECTION16:
1985 EOWRITE4(sc, port, v | EHCI_PS_CSC)(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(port)), ((v | 0x00000002))))
;
1986 break;
1987 case UHF_C_PORT_ENABLE17:
1988 EOWRITE4(sc, port, v | EHCI_PS_PEC)(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(port)), ((v | 0x00000008))))
;
1989 break;
1990 case UHF_C_PORT_SUSPEND18:
1991 /* how? */
1992 break;
1993 case UHF_C_PORT_OVER_CURRENT19:
1994 EOWRITE4(sc, port, v | EHCI_PS_OCC)(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(port)), ((v | 0x00000020))))
;
1995 break;
1996 case UHF_C_PORT_RESET20:
1997 sc->sc_isreset = 0;
1998 break;
1999 default:
2000 err = USBD_IOERROR;
2001 goto ret;
2002 }
2003 break;
2004 case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE)((0x06) | (((0x80 | 0x20 | 0x00)) << 8)):
2005 if ((value & 0xff) != 0) {
2006 err = USBD_IOERROR;
2007 goto ret;
2008 }
2009 hubd = ehci_hubd;
2010 hubd.bNbrPorts = sc->sc_noport;
2011 v = EREAD4(sc, EHCI_HCSPARAMS)(((sc)->iot)->read_4(((sc)->ioh), ((0x04))));
2012 USETW(hubd.wHubCharacteristics,(*(u_int16_t *)(hubd.wHubCharacteristics) = ((((v) & 0x10
) ? 0x0001 : 0x0002) | (((v) & 0x10000) ? 0x0080 : 0)))
2013 (EHCI_HCS_PPC(v) ? UHD_PWR_INDIVIDUAL : UHD_PWR_NO_SWITCH) |(*(u_int16_t *)(hubd.wHubCharacteristics) = ((((v) & 0x10
) ? 0x0001 : 0x0002) | (((v) & 0x10000) ? 0x0080 : 0)))
2014 (EHCI_HCS_P_INDICATOR(v) ? UHD_PORT_IND : 0))(*(u_int16_t *)(hubd.wHubCharacteristics) = ((((v) & 0x10
) ? 0x0001 : 0x0002) | (((v) & 0x10000) ? 0x0080 : 0)))
;
2015 hubd.bPwrOn2PwrGood = 200; /* XXX can't find out? */
2016 for (i = 0, l = sc->sc_noport; l > 0; i++, l -= 8, v >>= 8)
2017 hubd.DeviceRemovable[i++] = 0; /* XXX can't find out? */
2018 hubd.bDescLength = USB_HUB_DESCRIPTOR_SIZE8 + i;
2019 l = min(len, hubd.bDescLength);
2020 totlen = l;
2021 memcpy(buf, &hubd, l)__builtin_memcpy((buf), (&hubd), (l));
2022 break;
2023 case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE)((0x00) | (((0x80 | 0x20 | 0x00)) << 8)):
2024 if (len != 4) {
2025 err = USBD_IOERROR;
2026 goto ret;
2027 }
2028 memset(buf, 0, len)__builtin_memset((buf), (0), (len)); /* ? XXX */
2029 totlen = len;
2030 break;
2031 case C(UR_GET_STATUS, UT_READ_CLASS_OTHER)((0x00) | (((0x80 | 0x20 | 0x03)) << 8)):
2032 DPRINTFN(8,("ehci_root_ctrl_start: get port status i=%d\n",
2033 index));
2034 if (index < 1 || index > sc->sc_noport) {
2035 err = USBD_IOERROR;
2036 goto ret;
2037 }
2038 if (len != 4) {
2039 err = USBD_IOERROR;
2040 goto ret;
2041 }
2042 v = EOREAD4(sc, EHCI_PORTSC(index))(((sc)->iot)->read_4(((sc)->ioh), ((sc)->sc_offs+
((0x40+4*(index))))))
;
2043 DPRINTFN(8,("ehci_root_ctrl_start: port status=0x%04x\n", v));
2044 i = UPS_HIGH_SPEED0x0400;
2045 if (v & EHCI_PS_CS0x00000001) i |= UPS_CURRENT_CONNECT_STATUS0x0001;
2046 if (v & EHCI_PS_PE0x00000004) i |= UPS_PORT_ENABLED0x0002;
2047 if (v & EHCI_PS_SUSP0x00000080) i |= UPS_SUSPEND0x0004;
2048 if (v & EHCI_PS_OCA0x00000010) i |= UPS_OVERCURRENT_INDICATOR0x0008;
2049 if (v & EHCI_PS_PR0x00000100) i |= UPS_RESET0x0010;
2050 if (v & EHCI_PS_PP0x00001000) i |= UPS_PORT_POWER0x0100;
2051 USETW(ps.wPortStatus, i)(*(u_int16_t *)(ps.wPortStatus) = (i));
2052 i = 0;
2053 if (v & EHCI_PS_CSC0x00000002) i |= UPS_C_CONNECT_STATUS0x0001;
2054 if (v & EHCI_PS_PEC0x00000008) i |= UPS_C_PORT_ENABLED0x0002;
2055 if (v & EHCI_PS_OCC0x00000020) i |= UPS_C_OVERCURRENT_INDICATOR0x0008;
2056 if (sc->sc_isreset) i |= UPS_C_PORT_RESET0x0010;
2057 USETW(ps.wPortChange, i)(*(u_int16_t *)(ps.wPortChange) = (i));
2058 l = min(len, sizeof(ps));
2059 memcpy(buf, &ps, l)__builtin_memcpy((buf), (&ps), (l));
2060 totlen = l;
2061 break;
2062 case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE)((0x07) | (((0x00 | 0x20 | 0x00)) << 8)):
2063 err = USBD_IOERROR;
2064 goto ret;
2065 case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE)((0x03) | (((0x00 | 0x20 | 0x00)) << 8)):
2066 break;
2067 case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER)((0x03) | (((0x00 | 0x20 | 0x03)) << 8)):
2068 if (index < 1 || index > sc->sc_noport) {
2069 err = USBD_IOERROR;
2070 goto ret;
2071 }
2072 port = EHCI_PORTSC(index)(0x40+4*(index));
2073 v = EOREAD4(sc, port)(((sc)->iot)->read_4(((sc)->ioh), ((sc)->sc_offs+
(port))))
&~ EHCI_PS_CLEAR(0x00000020|0x00000008|0x00000002);
2074 switch(value) {
2075 case UHF_PORT_ENABLE1:
2076 EOWRITE4(sc, port, v | EHCI_PS_PE)(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(port)), ((v | 0x00000004))))
;
2077 break;
2078 case UHF_PORT_SUSPEND2:
2079 EOWRITE4(sc, port, v | EHCI_PS_SUSP)(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(port)), ((v | 0x00000080))))
;
2080 break;
2081 case UHF_PORT_DISOWN_TO_1_130:
2082 /* enter to Port Reset State */
2083 v &= ~EHCI_PS_PE0x00000004;
2084 EOWRITE4(sc, port, v | EHCI_PS_PR)(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(port)), ((v | 0x00000100))))
;
2085 ehci_disown(sc, index, 0);
2086 break;
2087 case UHF_PORT_RESET4:
2088 DPRINTFN(5,("ehci_root_ctrl_start: reset port %d\n",
2089 index));
2090 if (EHCI_PS_IS_LOWSPEED(v)(((v) & 0x00000c00) == 0x00000400)) {
2091 /* Low speed device, give up ownership. */
2092 ehci_disown(sc, index, 1);
2093 break;
2094 }
2095 /* Start reset sequence. */
2096 v &= ~ (EHCI_PS_PE0x00000004 | EHCI_PS_PR0x00000100);
2097 EOWRITE4(sc, port, v | EHCI_PS_PR)(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(port)), ((v | 0x00000100))))
;
2098 /* Wait for reset to complete. */
2099 usb_delay_ms(&sc->sc_bus, USB_PORT_ROOT_RESET_DELAY100);
2100 if (sc->sc_bus.dying) {
2101 err = USBD_IOERROR;
2102 goto ret;
2103 }
2104 /* Terminate reset sequence. */
2105 v = EOREAD4(sc, port)(((sc)->iot)->read_4(((sc)->ioh), ((sc)->sc_offs+
(port))))
;
2106 EOWRITE4(sc, port, v & ~EHCI_PS_PR)(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(port)), ((v & ~0x00000100))))
;
2107 /* Wait for HC to complete reset. */
2108 usb_delay_ms(&sc->sc_bus, EHCI_PORT_RESET_COMPLETE2);
2109 if (sc->sc_bus.dying) {
2110 err = USBD_IOERROR;
2111 goto ret;
2112 }
2113 v = EOREAD4(sc, port)(((sc)->iot)->read_4(((sc)->ioh), ((sc)->sc_offs+
(port))))
;
2114 DPRINTF(("ehci after reset, status=0x%08x\n", v));
2115 if (v & EHCI_PS_PR0x00000100) {
2116 printf("%s: port reset timeout\n",
2117 sc->sc_bus.bdev.dv_xname);
2118 err = USBD_IOERROR;
2119 goto ret;
2120 }
2121 if (!(v & EHCI_PS_PE0x00000004)) {
2122 /* Not a high speed device, give up ownership.*/
2123 ehci_disown(sc, index, 0);
2124 break;
2125 }
2126 sc->sc_isreset = 1;
2127 DPRINTF(("ehci port %d reset, status = 0x%08x\n",
2128 index, v));
2129 break;
2130 case UHF_PORT_POWER8:
2131 DPRINTFN(2,("ehci_root_ctrl_start: "
2132 "set port power %d\n", index));
2133 EOWRITE4(sc, port, v | EHCI_PS_PP)(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(port)), ((v | 0x00001000))))
;
2134 break;
2135 case UHF_PORT_TEST21:
2136 DPRINTFN(2,("ehci_root_ctrl_start: "
2137 "set port test %d\n", index));
2138 break;
2139 case UHF_PORT_INDICATOR22:
2140 DPRINTFN(2,("ehci_root_ctrl_start: "
2141 "set port ind %d\n", index));
2142 EOWRITE4(sc, port, v | EHCI_PS_PIC)(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(port)), ((v | 0x0000c000))))
;
2143 break;
2144 default:
2145 err = USBD_IOERROR;
2146 goto ret;
2147 }
2148 break;
2149 case C(UR_CLEAR_TT_BUFFER, UT_WRITE_CLASS_OTHER)((0x08) | (((0x00 | 0x20 | 0x03)) << 8)):
2150 case C(UR_RESET_TT, UT_WRITE_CLASS_OTHER)((0x09) | (((0x00 | 0x20 | 0x03)) << 8)):
2151 case C(UR_GET_TT_STATE, UT_READ_CLASS_OTHER)((0x0a) | (((0x80 | 0x20 | 0x03)) << 8)):
2152 case C(UR_STOP_TT, UT_WRITE_CLASS_OTHER)((0x0b) | (((0x00 | 0x20 | 0x03)) << 8)):
2153 break;
2154 default:
2155 err = USBD_IOERROR;
2156 goto ret;
2157 }
2158 xfer->actlen = totlen;
2159 err = USBD_NORMAL_COMPLETION;
2160 ret:
2161 xfer->status = err;
2162 s = splusb()splraise(0x5);
2163 usb_transfer_complete(xfer);
2164 splx(s)spllower(s);
2165 return (err);
2166}
2167
2168void
2169ehci_disown(struct ehci_softc *sc, int index, int lowspeed)
2170{
2171 int port;
2172 u_int32_t v;
2173
2174 port = EHCI_PORTSC(index)(0x40+4*(index));
2175 v = EOREAD4(sc, port)(((sc)->iot)->read_4(((sc)->ioh), ((sc)->sc_offs+
(port))))
&~ EHCI_PS_CLEAR(0x00000020|0x00000008|0x00000002);
2176 EOWRITE4(sc, port, v | EHCI_PS_PO)(((sc)->iot)->write_4(((sc)->ioh), ((sc)->sc_offs
+(port)), ((v | 0x00002000))))
;
2177}
2178
2179/* Abort a root control request. */
2180void
2181ehci_root_ctrl_abort(struct usbd_xfer *xfer)
2182{
2183 /* Nothing to do, all transfers are synchronous. */
2184}
2185
2186/* Close the root pipe. */
2187void
2188ehci_root_ctrl_close(struct usbd_pipe *pipe)
2189{
2190 /* Nothing to do. */
2191}
2192
2193void
2194ehci_root_intr_done(struct usbd_xfer *xfer)
2195{
2196}
2197
2198usbd_status
2199ehci_root_intr_transfer(struct usbd_xfer *xfer)
2200{
2201 usbd_status err;
2202
2203 /* Insert last in queue. */
2204 err = usb_insert_transfer(xfer);
2205 if (err)
2206 return (err);
2207
2208 /* Pipe isn't running, start first */
2209 return (ehci_root_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue)((&xfer->pipe->queue)->sqh_first)));
2210}
2211
2212usbd_status
2213ehci_root_intr_start(struct usbd_xfer *xfer)
2214{
2215 struct ehci_softc *sc = (struct ehci_softc *)xfer->device->bus;
2216
2217 if (sc->sc_bus.dying)
2218 return (USBD_IOERROR);
2219
2220 sc->sc_intrxfer = xfer;
2221
2222 return (USBD_IN_PROGRESS);
2223}
2224
2225void
2226ehci_root_intr_abort(struct usbd_xfer *xfer)
2227{
2228 struct ehci_softc *sc = (struct ehci_softc *)xfer->device->bus;
2229 int s;
2230
2231 sc->sc_intrxfer = NULL((void *)0);
2232
2233 xfer->status = USBD_CANCELLED;
2234 s = splusb()splraise(0x5);
2235 usb_transfer_complete(xfer);
2236 splx(s)spllower(s);
2237}
2238
2239void
2240ehci_root_intr_close(struct usbd_pipe *pipe)
2241{
2242}
2243
2244void
2245ehci_root_ctrl_done(struct usbd_xfer *xfer)
2246{
2247}
2248
2249struct ehci_soft_qh *
2250ehci_alloc_sqh(struct ehci_softc *sc)
2251{
2252 struct ehci_soft_qh *sqh = NULL((void *)0);
2253 usbd_status err;
2254 int i, offs;
2255 struct usb_dma dma;
2256 int s;
2257
2258 s = splusb()splraise(0x5);
2259 if (sc->sc_freeqhs == NULL((void *)0)) {
2260 DPRINTFN(2, ("ehci_alloc_sqh: allocating chunk\n"));
2261 err = usb_allocmem(&sc->sc_bus, EHCI_SQH_SIZE((sizeof (struct ehci_soft_qh) + 32 - 1) / 32 * 32) * EHCI_SQH_CHUNK(0x1000 / ((sizeof (struct ehci_soft_qh) + 32 - 1) / 32 * 32)
)
,
2262 EHCI_PAGE_SIZE0x1000, USB_DMA_COHERENT(1 << 0), &dma);
2263 if (err)
2264 goto out;
2265 for (i = 0; i < EHCI_SQH_CHUNK(0x1000 / ((sizeof (struct ehci_soft_qh) + 32 - 1) / 32 * 32)
)
; i++) {
2266 offs = i * EHCI_SQH_SIZE((sizeof (struct ehci_soft_qh) + 32 - 1) / 32 * 32);
2267 sqh = KERNADDR(&dma, offs)((void *)((char *)((&dma)->block->kaddr + (&dma
)->offs) + (offs)))
;
2268 sqh->physaddr = DMAADDR(&dma, offs)((&dma)->block->map->dm_segs[0].ds_addr + (&
dma)->offs + (offs))
;
2269 sqh->dma = dma;
2270 sqh->offs = offs;
2271 sqh->next = sc->sc_freeqhs;
2272 sc->sc_freeqhs = sqh;
2273 }
2274 }
2275 sqh = sc->sc_freeqhs;
2276 sc->sc_freeqhs = sqh->next;
2277 memset(&sqh->qh, 0, sizeof(struct ehci_qh))__builtin_memset((&sqh->qh), (0), (sizeof(struct ehci_qh
)))
;
2278 sqh->next = NULL((void *)0);
2279 sqh->prev = NULL((void *)0);
2280
2281out:
2282 splx(s)spllower(s);
2283 return (sqh);
2284}
2285
2286void
2287ehci_free_sqh(struct ehci_softc *sc, struct ehci_soft_qh *sqh)
2288{
2289 int s;
2290
2291 s = splusb()splraise(0x5);
2292 sqh->next = sc->sc_freeqhs;
2293 sc->sc_freeqhs = sqh;
2294 splx(s)spllower(s);
2295}
2296
2297struct ehci_soft_qtd *
2298ehci_alloc_sqtd(struct ehci_softc *sc)
2299{
2300 struct ehci_soft_qtd *sqtd = NULL((void *)0);
2301 usbd_status err;
2302 int i, offs;
2303 struct usb_dma dma;
2304 int s;
2305
2306 s = splusb()splraise(0x5);
2307 if (sc->sc_freeqtds == NULL((void *)0)) {
2308 DPRINTFN(2, ("ehci_alloc_sqtd: allocating chunk\n"));
2309 err = usb_allocmem(&sc->sc_bus, EHCI_SQTD_SIZE((sizeof (struct ehci_soft_qtd) + 32 - 1) / 32 * 32)*EHCI_SQTD_CHUNK(0x1000 / ((sizeof (struct ehci_soft_qtd) + 32 - 1) / 32 * 32
))
,
2310 EHCI_PAGE_SIZE0x1000, USB_DMA_COHERENT(1 << 0), &dma);
2311 if (err)
2312 goto out;
2313 for(i = 0; i < EHCI_SQTD_CHUNK(0x1000 / ((sizeof (struct ehci_soft_qtd) + 32 - 1) / 32 * 32
))
; i++) {
2314 offs = i * EHCI_SQTD_SIZE((sizeof (struct ehci_soft_qtd) + 32 - 1) / 32 * 32);
2315 sqtd = KERNADDR(&dma, offs)((void *)((char *)((&dma)->block->kaddr + (&dma
)->offs) + (offs)))
;
2316 sqtd->physaddr = DMAADDR(&dma, offs)((&dma)->block->map->dm_segs[0].ds_addr + (&
dma)->offs + (offs))
;
2317 sqtd->dma = dma;
2318 sqtd->offs = offs;
2319 sqtd->nextqtd = sc->sc_freeqtds;
2320 sc->sc_freeqtds = sqtd;
2321 }
2322 }
2323
2324 sqtd = sc->sc_freeqtds;
2325 sc->sc_freeqtds = sqtd->nextqtd;
2326 memset(&sqtd->qtd, 0, sizeof(struct ehci_qtd))__builtin_memset((&sqtd->qtd), (0), (sizeof(struct ehci_qtd
)))
;
2327 sqtd->nextqtd = NULL((void *)0);
2328
2329out:
2330 splx(s)spllower(s);
2331 return (sqtd);
2332}
2333
2334void
2335ehci_free_sqtd(struct ehci_softc *sc, struct ehci_soft_qtd *sqtd)
2336{
2337 int s;
2338
2339 s = splusb()splraise(0x5);
2340 sqtd->nextqtd = sc->sc_freeqtds;
2341 sc->sc_freeqtds = sqtd;
2342 splx(s)spllower(s);
2343}
2344
2345usbd_status
2346ehci_alloc_sqtd_chain(struct ehci_softc *sc, u_int alen, struct usbd_xfer *xfer,
2347 struct ehci_soft_qtd **sp, struct ehci_soft_qtd **ep)
2348{
2349 struct ehci_soft_qtd *next, *cur;
2350 ehci_physaddr_t dataphys, dataphyspage, dataphyslastpage, nextphys;
2351 u_int32_t qtdstatus;
2352 u_int len, curlen;
2353 int mps, i, iscontrol, forceshort;
2354 int rd = usbd_xfer_isread(xfer);
2355 struct usb_dma *dma = &xfer->dmabuf;
2356
2357 DPRINTFN(alen<4*4096,("ehci_alloc_sqtd_chain: start len=%d\n", alen));
2358
2359 len = alen;
2360 iscontrol = UE_GET_XFERTYPE(xfer->pipe->endpoint->edesc->bmAttributes)((xfer->pipe->endpoint->edesc->bmAttributes) &
0x03)
==
2361 UE_CONTROL0x00;
2362
2363 dataphys = DMAADDR(dma, 0)((dma)->block->map->dm_segs[0].ds_addr + (dma)->offs
+ (0))
;
2364 dataphyslastpage = EHCI_PAGE(dataphys + len - 1)((dataphys + len - 1) &~ 0xfff);
2365 qtdstatus = EHCI_QTD_ACTIVE0x80 |
2366 EHCI_QTD_SET_PID(rd ? EHCI_QTD_PID_IN : EHCI_QTD_PID_OUT)((rd ? 0x1 : 0x0) << 8) |
2367 EHCI_QTD_SET_CERR(3)((3) << 10); /* IOC and BYTES set below */
2368 mps = UGETW(xfer->pipe->endpoint->edesc->wMaxPacketSize)(*(u_int16_t *)(xfer->pipe->endpoint->edesc->wMaxPacketSize
))
;
2369 forceshort = ((xfer->flags & USBD_FORCE_SHORT_XFER0x08) || len == 0) &&
2370 len % mps == 0;
2371 /*
2372 * The control transfer data stage always starts with a toggle of 1.
2373 * For other transfers we let the hardware track the toggle state.
2374 */
2375 if (iscontrol)
2376 qtdstatus |= EHCI_QTD_SET_TOGGLE(1)((1) << 31);
2377
2378 cur = ehci_alloc_sqtd(sc);
2379 *sp = cur;
2380 if (cur == NULL((void *)0))
2381 goto nomem;
2382
2383 usb_syncmem(dma, 0, alen,
2384 rd ? BUS_DMASYNC_PREREAD0x01 : BUS_DMASYNC_PREWRITE0x04);
2385 for (;;) {
2386 dataphyspage = EHCI_PAGE(dataphys)((dataphys) &~ 0xfff);
2387 /* The EHCI hardware can handle at most 5 pages. */
2388 if (dataphyslastpage - dataphyspage <
2389 EHCI_QTD_NBUFFERS5 * EHCI_PAGE_SIZE0x1000) {
2390 /* we can handle it in this QTD */
2391 curlen = len;
2392 } else {
2393 /* must use multiple TDs, fill as much as possible. */
2394 curlen = EHCI_QTD_NBUFFERS5 * EHCI_PAGE_SIZE0x1000 -
2395 EHCI_PAGE_OFFSET(dataphys)((dataphys) & 0xfff);
2396
2397 if (curlen > len) {
2398 DPRINTFN(1,("ehci_alloc_sqtd_chain: curlen=%u "
2399 "len=%u offs=0x%x\n", curlen, len,
2400 EHCI_PAGE_OFFSET(dataphys)));
2401 DPRINTFN(1,("lastpage=0x%x page=0x%x phys=0x%x\n",
2402 dataphyslastpage, dataphyspage, dataphys));
2403 curlen = len;
2404 }
2405
2406 /* the length must be a multiple of the max size */
2407 curlen -= curlen % mps;
2408 DPRINTFN(1,("ehci_alloc_sqtd_chain: multiple QTDs, "
2409 "curlen=%u\n", curlen));
2410 }
2411
2412 DPRINTFN(4,("ehci_alloc_sqtd_chain: dataphys=0x%08x "
2413 "dataphyslastpage=0x%08x len=%u curlen=%u\n",
2414 dataphys, dataphyslastpage, len, curlen));
2415 len -= curlen;
2416
2417 /*
2418 * Allocate another transfer if there's more data left,
2419 * or if force last short transfer flag is set and we're
2420 * allocating a multiple of the max packet size.
2421 */
2422 if (len != 0 || forceshort) {
2423 next = ehci_alloc_sqtd(sc);
2424 if (next == NULL((void *)0))
2425 goto nomem;
2426 nextphys = htole32(next->physaddr)((__uint32_t)(next->physaddr));
2427 } else {
2428 next = NULL((void *)0);
2429 nextphys = htole32(EHCI_LINK_TERMINATE)((__uint32_t)(0x00000001));
2430 }
2431
2432 for (i = 0; i * EHCI_PAGE_SIZE0x1000 <
2433 curlen + EHCI_PAGE_OFFSET(dataphys)((dataphys) & 0xfff); i++) {
2434 ehci_physaddr_t a = dataphys + i * EHCI_PAGE_SIZE0x1000;
2435 if (i != 0) /* use offset only in first buffer */
2436 a = EHCI_PAGE(a)((a) &~ 0xfff);
2437#ifdef DIAGNOSTIC1
2438 if (i >= EHCI_QTD_NBUFFERS5) {
2439 printf("ehci_alloc_sqtd_chain: i=%d\n", i);
2440 goto nomem;
2441 }
2442#endif
2443 cur->qtd.qtd_buffer[i] = htole32(a)((__uint32_t)(a));
2444 cur->qtd.qtd_buffer_hi[i] = 0;
2445 }
2446 cur->nextqtd = next;
2447 cur->qtd.qtd_next = cur->qtd.qtd_altnext = nextphys;
2448 cur->qtd.qtd_status = htole32(qtdstatus |((__uint32_t)(qtdstatus | ((curlen) << 16)))
2449 EHCI_QTD_SET_BYTES(curlen))((__uint32_t)(qtdstatus | ((curlen) << 16)));
2450 cur->len = curlen;
2451 DPRINTFN(10,("ehci_alloc_sqtd_chain: cbp=0x%08x end=0x%08x\n",
2452 dataphys, dataphys + curlen));
2453 DPRINTFN(10,("ehci_alloc_sqtd_chain: curlen=%u\n", curlen));
2454 if (iscontrol) {
2455 /*
2456 * adjust the toggle based on the number of packets
2457 * in this qtd
2458 */
2459 if ((((curlen + mps - 1) / mps) & 1) || curlen == 0)
2460 qtdstatus ^= EHCI_QTD_TOGGLE_MASK0x80000000;
2461 }
2462 if (len == 0) {
2463 if (! forceshort)
2464 break;
2465 forceshort = 0;
2466 }
2467 usb_syncmem(&cur->dma, cur->offs, sizeof(cur->qtd),
2468 BUS_DMASYNC_PREWRITE0x04 | BUS_DMASYNC_PREREAD0x01);
2469 DPRINTFN(10,("ehci_alloc_sqtd_chain: extend chain\n"));
2470 dataphys += curlen;
2471 cur = next;
2472 }
2473 cur->qtd.qtd_status |= htole32(EHCI_QTD_IOC)((__uint32_t)(0x00008000));
2474 usb_syncmem(&cur->dma, cur->offs, sizeof(cur->qtd),
2475 BUS_DMASYNC_PREWRITE0x04 | BUS_DMASYNC_PREREAD0x01);
2476 *ep = cur;
2477
2478 DPRINTFN(10,("ehci_alloc_sqtd_chain: return sqtd=%p sqtdend=%p\n",
2479 *sp, *ep));
2480
2481 return (USBD_NORMAL_COMPLETION);
2482
2483 nomem:
2484 /* XXX free chain */
2485 DPRINTFN(-1,("ehci_alloc_sqtd_chain: no memory\n"));
2486 return (USBD_NOMEM);
2487}
2488
2489void
2490ehci_free_sqtd_chain(struct ehci_softc *sc, struct ehci_xfer *ex)
2491{
2492 struct ehci_pipe *epipe = (struct ehci_pipe *)ex->xfer.pipe;
2493 struct ehci_soft_qtd *sqtd, *next;
2494
2495 DPRINTFN(10,("ehci_free_sqtd_chain: sqtd=%p\n", ex->sqtdstart));
2496
2497 for (sqtd = ex->sqtdstart_TD.sqtd.start; sqtd != NULL((void *)0); sqtd = next) {
2498 next = sqtd->nextqtd;
2499 ehci_free_sqtd(sc, sqtd);
2500 }
2501 ex->sqtdstart_TD.sqtd.start = ex->sqtdend_TD.sqtd.end = NULL((void *)0);
2502 epipe->sqh->sqtd = NULL((void *)0);
2503}
2504
2505struct ehci_soft_itd *
2506ehci_alloc_itd(struct ehci_softc *sc)
2507{
2508 struct ehci_soft_itd *itd, *freeitd;
2509 usbd_status err;
2510 int i, s, offs, frindex, previndex;
2511 struct usb_dma dma;
2512
2513 s = splusb()splraise(0x5);
2514
2515 /* Find an itd that wasn't freed this frame or last frame. This can
2516 * discard itds that were freed before frindex wrapped around
2517 * XXX - can this lead to thrashing? Could fix by enabling wrap-around
2518 * interrupt and fiddling with list when that happens */
2519 frindex = (EOREAD4(sc, EHCI_FRINDEX)(((sc)->iot)->read_4(((sc)->ioh), ((sc)->sc_offs+
(0x0c))))
+ 1) >> 3;
2520 previndex = (frindex != 0) ? frindex - 1 : sc->sc_flsize;
2521
2522 freeitd = NULL((void *)0);
2523 LIST_FOREACH(itd, &sc->sc_freeitds, u.free_list)for((itd) = ((&sc->sc_freeitds)->lh_first); (itd)!=
((void *)0); (itd) = ((itd)->u.free_list.le_next))
{
2524 if (itd->slot != frindex && itd->slot != previndex) {
2525 freeitd = itd;
2526 break;
2527 }
2528 }
2529
2530 if (freeitd == NULL((void *)0)) {
2531 err = usb_allocmem(&sc->sc_bus, EHCI_ITD_SIZE((sizeof(struct ehci_soft_itd) + 32 - 1) / 32 * 32) * EHCI_ITD_CHUNK(0x1000 / ((sizeof(struct ehci_soft_itd) + 32 - 1) / 32 * 32)
)
,
2532 EHCI_PAGE_SIZE0x1000, USB_DMA_COHERENT(1 << 0), &dma);
2533 if (err) {
2534 splx(s)spllower(s);
2535 return (NULL((void *)0));
2536 }
2537
2538 for (i = 0; i < EHCI_ITD_CHUNK(0x1000 / ((sizeof(struct ehci_soft_itd) + 32 - 1) / 32 * 32)
)
; i++) {
2539 offs = i * EHCI_ITD_SIZE((sizeof(struct ehci_soft_itd) + 32 - 1) / 32 * 32);
2540 itd = KERNADDR(&dma, offs)((void *)((char *)((&dma)->block->kaddr + (&dma
)->offs) + (offs)))
;
2541 itd->physaddr = DMAADDR(&dma, offs)((&dma)->block->map->dm_segs[0].ds_addr + (&
dma)->offs + (offs))
;
2542 itd->dma = dma;
2543 itd->offs = offs;
2544 LIST_INSERT_HEAD(&sc->sc_freeitds, itd, u.free_list)do { if (((itd)->u.free_list.le_next = (&sc->sc_freeitds
)->lh_first) != ((void *)0)) (&sc->sc_freeitds)->
lh_first->u.free_list.le_prev = &(itd)->u.free_list
.le_next; (&sc->sc_freeitds)->lh_first = (itd); (itd
)->u.free_list.le_prev = &(&sc->sc_freeitds)->
lh_first; } while (0)
;
2545 }
2546 freeitd = LIST_FIRST(&sc->sc_freeitds)((&sc->sc_freeitds)->lh_first);
2547 }
2548
2549 itd = freeitd;
2550 LIST_REMOVE(itd, u.free_list)do { if ((itd)->u.free_list.le_next != ((void *)0)) (itd)->
u.free_list.le_next->u.free_list.le_prev = (itd)->u.free_list
.le_prev; *(itd)->u.free_list.le_prev = (itd)->u.free_list
.le_next; ((itd)->u.free_list.le_prev) = ((void *)-1); ((itd
)->u.free_list.le_next) = ((void *)-1); } while (0)
;
2551 memset(&itd->itd, 0, sizeof(struct ehci_itd))__builtin_memset((&itd->itd), (0), (sizeof(struct ehci_itd
)))
;
2552 usb_syncmem(&itd->dma, itd->offs + offsetof(struct ehci_itd, itd_next)__builtin_offsetof(struct ehci_itd, itd_next),
2553 sizeof(itd->itd.itd_next), BUS_DMASYNC_PREWRITE0x04 |
2554 BUS_DMASYNC_PREREAD0x01);
2555
2556 itd->u.frame_list.next = NULL((void *)0);
2557 itd->u.frame_list.prev = NULL((void *)0);
2558 itd->xfer_next = NULL((void *)0);
2559 itd->slot = 0;
2560 splx(s)spllower(s);
2561
2562 return (itd);
2563}
2564
2565void
2566ehci_free_itd(struct ehci_softc *sc, struct ehci_soft_itd *itd)
2567{
2568 int s;
2569
2570 s = splusb()splraise(0x5);
2571 LIST_INSERT_HEAD(&sc->sc_freeitds, itd, u.free_list)do { if (((itd)->u.free_list.le_next = (&sc->sc_freeitds
)->lh_first) != ((void *)0)) (&sc->sc_freeitds)->
lh_first->u.free_list.le_prev = &(itd)->u.free_list
.le_next; (&sc->sc_freeitds)->lh_first = (itd); (itd
)->u.free_list.le_prev = &(&sc->sc_freeitds)->
lh_first; } while (0)
;
2572 splx(s)spllower(s);
2573}
2574
2575/*
2576 * Close a regular pipe.
2577 * Assumes that there are no pending transactions.
2578 */
2579void
2580ehci_close_pipe(struct usbd_pipe *pipe)
2581{
2582 struct ehci_pipe *epipe = (struct ehci_pipe *)pipe;
2583 struct ehci_softc *sc = (struct ehci_softc *)pipe->device->bus;
2584 struct ehci_soft_qh *sqh = epipe->sqh;
2585 int s;
2586
2587 s = splusb()splraise(0x5);
2588 ehci_rem_qh(sc, sqh);
2589 splx(s)spllower(s);
2590 pipe->endpoint->savedtoggle =
2591 EHCI_QTD_GET_TOGGLE(letoh32(sqh->qh.qh_qtd.qtd_status))(((((__uint32_t)(sqh->qh.qh_qtd.qtd_status))) >> 31)
& 0x1)
;
2592 ehci_free_sqh(sc, epipe->sqh);
2593}
2594
2595/*
2596 * Abort a device request.
2597 * If this routine is called at splusb() it guarantees that the request
2598 * will be removed from the hardware scheduling and that the callback
2599 * for it will be called with USBD_CANCELLED status.
2600 * It's impossible to guarantee that the requested transfer will not
2601 * have happened since the hardware runs concurrently.
2602 * If the transaction has already happened we rely on the ordinary
2603 * interrupt processing to process it.
2604 */
2605void
2606ehci_abort_xfer(struct usbd_xfer *xfer, usbd_status status)
2607{
2608 struct ehci_softc *sc = (struct ehci_softc *)xfer->device->bus;
2609 struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
2610 struct ehci_xfer *ex = (struct ehci_xfer*)xfer;
2611 struct ehci_soft_qh *sqh = epipe->sqh;
2612 struct ehci_soft_qtd *sqtd;
2613 int s;
2614
2615 if (sc->sc_bus.dying || xfer->status == USBD_NOT_STARTED) {
2616 s = splusb()splraise(0x5);
2617 if (xfer->status != USBD_NOT_STARTED)
2618 TAILQ_REMOVE(&sc->sc_intrhead, ex, inext)do { if (((ex)->inext.tqe_next) != ((void *)0)) (ex)->inext
.tqe_next->inext.tqe_prev = (ex)->inext.tqe_prev; else (
&sc->sc_intrhead)->tqh_last = (ex)->inext.tqe_prev
; *(ex)->inext.tqe_prev = (ex)->inext.tqe_next; ((ex)->
inext.tqe_prev) = ((void *)-1); ((ex)->inext.tqe_next) = (
(void *)-1); } while (0)
;
2619 xfer->status = status; /* make software ignore it */
2620 timeout_del(&xfer->timeout_handle);
2621 usb_rem_task(xfer->device, &xfer->abort_task);
2622#ifdef DIAGNOSTIC1
2623 ex->isdone = 1;
2624#endif
2625 usb_transfer_complete(xfer);
2626 splx(s)spllower(s);
2627 return;
2628 }
2629
2630 if (xfer->device->bus->intr_context)
2631 panic("ehci_abort_xfer: not in process context");
2632
2633 /*
2634 * If an abort is already in progress then just wait for it to
2635 * complete and return.
2636 */
2637 if (ex->ehci_xfer_flags & EHCI_XFER_ABORTING0x0001) {
2638 DPRINTFN(2, ("ehci_abort_xfer: already aborting\n"));
2639 /* No need to wait if we're aborting from a timeout. */
2640 if (status == USBD_TIMEOUT)
2641 return;
2642 /* Override the status which might be USBD_TIMEOUT. */
2643 xfer->status = status;
2644 DPRINTFN(2, ("ehci_abort_xfer: waiting for abort to finish\n"));
2645 ex->ehci_xfer_flags |= EHCI_XFER_ABORTWAIT0x0002;
2646 while (ex->ehci_xfer_flags & EHCI_XFER_ABORTING0x0001)
2647 tsleep_nsec(&ex->ehci_xfer_flags, PZERO22, "ehciaw", INFSLP0xffffffffffffffffULL);
2648 return;
2649 }
2650
2651 /*
2652 * Step 1: Make interrupt routine and timeouts ignore xfer.
2653 */
2654 s = splusb()splraise(0x5);
2655 ex->ehci_xfer_flags |= EHCI_XFER_ABORTING0x0001;
2656 xfer->status = status; /* make software ignore it */
2657 TAILQ_REMOVE(&sc->sc_intrhead, ex, inext)do { if (((ex)->inext.tqe_next) != ((void *)0)) (ex)->inext
.tqe_next->inext.tqe_prev = (ex)->inext.tqe_prev; else (
&sc->sc_intrhead)->tqh_last = (ex)->inext.tqe_prev
; *(ex)->inext.tqe_prev = (ex)->inext.tqe_next; ((ex)->
inext.tqe_prev) = ((void *)-1); ((ex)->inext.tqe_next) = (
(void *)-1); } while (0)
;
2658 timeout_del(&xfer->timeout_handle);
2659 usb_rem_task(xfer->device, &xfer->abort_task);
2660 splx(s)spllower(s);
2661
2662 /*
2663 * Step 2: Deactivate all of the qTDs that we will be removing,
2664 * otherwise the queue head may go active again.
2665 */
2666 usb_syncmem(&sqh->dma,
2667 sqh->offs + offsetof(struct ehci_qh, qh_qtd.qtd_status)__builtin_offsetof(struct ehci_qh, qh_qtd.qtd_status),
2668 sizeof(sqh->qh.qh_qtd.qtd_status),
2669 BUS_DMASYNC_POSTWRITE0x08 | BUS_DMASYNC_POSTREAD0x02);
2670 sqh->qh.qh_qtd.qtd_status = htole32(EHCI_QTD_HALTED)((__uint32_t)(0x40));
2671 usb_syncmem(&sqh->dma,
2672 sqh->offs + offsetof(struct ehci_qh, qh_qtd.qtd_status)__builtin_offsetof(struct ehci_qh, qh_qtd.qtd_status),
2673 sizeof(sqh->qh.qh_qtd.qtd_status),
2674 BUS_DMASYNC_PREWRITE0x04 | BUS_DMASYNC_PREREAD0x01);
2675
2676 for (sqtd = ex->sqtdstart_TD.sqtd.start; sqtd != NULL((void *)0); sqtd = sqtd->nextqtd) {
2677 usb_syncmem(&sqtd->dma,
2678 sqtd->offs + offsetof(struct ehci_qtd, qtd_status)__builtin_offsetof(struct ehci_qtd, qtd_status),
2679 sizeof(sqtd->qtd.qtd_status),
2680 BUS_DMASYNC_POSTWRITE0x08 | BUS_DMASYNC_POSTREAD0x02);
2681 sqtd->qtd.qtd_status = htole32(EHCI_QTD_HALTED)((__uint32_t)(0x40));
2682 usb_syncmem(&sqtd->dma,
2683 sqtd->offs + offsetof(struct ehci_qtd, qtd_status)__builtin_offsetof(struct ehci_qtd, qtd_status),
2684 sizeof(sqtd->qtd.qtd_status),
2685 BUS_DMASYNC_PREWRITE0x04 | BUS_DMASYNC_PREREAD0x01);
2686 }
2687 ehci_sync_hc(sc);
2688
2689 /*
2690 * Step 3: Make sure the soft interrupt routine has run. This
2691 * should remove any completed items off the queue.
2692 * The hardware has no reference to completed items (TDs).
2693 * It's safe to remove them at any time.
2694 */
2695 s = splusb()splraise(0x5);
2696 sc->sc_softwake = 1;
2697 usb_schedsoftintr(&sc->sc_bus);
2698 tsleep_nsec(&sc->sc_softwake, PZERO22, "ehciab", INFSLP0xffffffffffffffffULL);
2699
2700#ifdef DIAGNOSTIC1
2701 ex->isdone = 1;
2702#endif
2703 /* Do the wakeup first to avoid touching the xfer after the callback. */
2704 ex->ehci_xfer_flags &= ~EHCI_XFER_ABORTING0x0001;
2705 if (ex->ehci_xfer_flags & EHCI_XFER_ABORTWAIT0x0002) {
2706 ex->ehci_xfer_flags &= ~EHCI_XFER_ABORTWAIT0x0002;
2707 wakeup(&ex->ehci_xfer_flags);
2708 }
2709 usb_transfer_complete(xfer);
2710
2711 splx(s)spllower(s);
2712}
2713
2714void
2715ehci_abort_isoc_xfer(struct usbd_xfer *xfer, usbd_status status)
2716{
2717 struct ehci_softc *sc = (struct ehci_softc *)xfer->device->bus;
2718 struct ehci_xfer *ex = (struct ehci_xfer *)xfer;
2719 ehci_isoc_trans_t trans_status;
2720 struct ehci_soft_itd *itd;
2721 int i;
2722
2723 splsoftassert(IPL_SOFTUSB)do { if (splassert_ctl > 0) { splassert_check(0x5, __func__
); } } while (0)
;
2724
2725 if (sc->sc_bus.dying || xfer->status == USBD_NOT_STARTED) {
2726 if (xfer->status != USBD_NOT_STARTED)
2727 TAILQ_REMOVE(&sc->sc_intrhead, ex, inext)do { if (((ex)->inext.tqe_next) != ((void *)0)) (ex)->inext
.tqe_next->inext.tqe_prev = (ex)->inext.tqe_prev; else (
&sc->sc_intrhead)->tqh_last = (ex)->inext.tqe_prev
; *(ex)->inext.tqe_prev = (ex)->inext.tqe_next; ((ex)->
inext.tqe_prev) = ((void *)-1); ((ex)->inext.tqe_next) = (
(void *)-1); } while (0)
;
2728 xfer->status = status;
2729 timeout_del(&xfer->timeout_handle);
2730 usb_rem_task(xfer->device, &xfer->abort_task);
2731 usb_transfer_complete(xfer);
2732 return;
2733 }
2734
2735 /* Transfer is already done. */
2736 if (xfer->status != USBD_IN_PROGRESS) {
2737 DPRINTF(("%s: already done \n", __func__));
2738 return;
2739 }
2740
2741
2742#ifdef DIAGNOSTIC1
2743 ex->isdone = 1;
2744#endif
2745 xfer->status = status;
2746 TAILQ_REMOVE(&sc->sc_intrhead, ex, inext)do { if (((ex)->inext.tqe_next) != ((void *)0)) (ex)->inext
.tqe_next->inext.tqe_prev = (ex)->inext.tqe_prev; else (
&sc->sc_intrhead)->tqh_last = (ex)->inext.tqe_prev
; *(ex)->inext.tqe_prev = (ex)->inext.tqe_next; ((ex)->
inext.tqe_prev) = ((void *)-1); ((ex)->inext.tqe_next) = (
(void *)-1); } while (0)
;
2747 timeout_del(&xfer->timeout_handle);
2748 usb_rem_task(xfer->device, &xfer->abort_task);
2749
2750 if (xfer->device->speed == USB_SPEED_HIGH3) {
2751 for (itd = ex->itdstart_TD.itd.start; itd != NULL((void *)0); itd = itd->xfer_next) {
2752 usb_syncmem(&itd->dma,
2753 itd->offs + offsetof(struct ehci_itd, itd_ctl)__builtin_offsetof(struct ehci_itd, itd_ctl),
2754 sizeof(itd->itd.itd_ctl),
2755 BUS_DMASYNC_POSTWRITE0x08 | BUS_DMASYNC_POSTREAD0x02);
2756
2757 for (i = 0; i < 8; i++) {
2758 trans_status = le32toh(itd->itd.itd_ctl[i])((__uint32_t)(itd->itd.itd_ctl[i]));
2759 trans_status &= ~EHCI_ITD_ACTIVE0x80000000;
2760 itd->itd.itd_ctl[i] = htole32(trans_status)((__uint32_t)(trans_status));
2761 }
2762
2763 usb_syncmem(&itd->dma,
2764 itd->offs + offsetof(struct ehci_itd, itd_ctl)__builtin_offsetof(struct ehci_itd, itd_ctl),
2765 sizeof(itd->itd.itd_ctl),
2766 BUS_DMASYNC_PREWRITE0x04 | BUS_DMASYNC_PREREAD0x01);
2767 }
2768 } else {
2769 for (itd = ex->itdstart_TD.itd.start; itd != NULL((void *)0); itd = itd->xfer_next) {
2770 usb_syncmem(&itd->dma,
2771 itd->offs + offsetof(struct ehci_sitd, sitd_trans)__builtin_offsetof(struct ehci_sitd, sitd_trans),
2772 sizeof(itd->sitd.sitd_trans),
2773 BUS_DMASYNC_POSTWRITE0x08 | BUS_DMASYNC_POSTREAD0x02);
2774
2775 trans_status = le32toh(itd->sitd.sitd_trans)((__uint32_t)(itd->sitd.sitd_trans));
2776 trans_status &= ~EHCI_SITD_ACTIVE0x80;
2777 itd->sitd.sitd_trans = htole32(trans_status)((__uint32_t)(trans_status));
2778
2779 usb_syncmem(&itd->dma,
2780 itd->offs + offsetof(struct ehci_sitd, sitd_trans)__builtin_offsetof(struct ehci_sitd, sitd_trans),
2781 sizeof(itd->sitd.sitd_trans),
2782 BUS_DMASYNC_PREWRITE0x04 | BUS_DMASYNC_PREREAD0x01);
2783 }
2784 }
2785
2786 sc->sc_softwake = 1;
2787 usb_schedsoftintr(&sc->sc_bus);
2788 tsleep_nsec(&sc->sc_softwake, PZERO22, "ehciab", INFSLP0xffffffffffffffffULL);
2789
2790 usb_transfer_complete(xfer);
2791}
2792
2793void
2794ehci_timeout(void *addr)
2795{
2796 struct usbd_xfer *xfer = addr;
2797 struct ehci_softc *sc = (struct ehci_softc *)xfer->device->bus;
2798
2799 if (sc->sc_bus.dying) {
2800 ehci_timeout_task(addr);
2801 return;
2802 }
2803
2804 usb_init_task(&xfer->abort_task, ehci_timeout_task, addr,((&xfer->abort_task)->fun = (ehci_timeout_task), (&
xfer->abort_task)->arg = (addr), (&xfer->abort_task
)->type = (2), (&xfer->abort_task)->state = 0x0)
2805 USB_TASK_TYPE_ABORT)((&xfer->abort_task)->fun = (ehci_timeout_task), (&
xfer->abort_task)->arg = (addr), (&xfer->abort_task
)->type = (2), (&xfer->abort_task)->state = 0x0)
;
2806 usb_add_task(xfer->device, &xfer->abort_task);
2807}
2808
2809void
2810ehci_timeout_task(void *addr)
2811{
2812 struct usbd_xfer *xfer = addr;
2813 int s;
2814
2815 s = splusb()splraise(0x5);
2816 ehci_abort_xfer(xfer, USBD_TIMEOUT);
2817 splx(s)spllower(s);
2818}
2819
2820/*
2821 * Some EHCI chips from VIA / ATI seem to trigger interrupts before writing
2822 * back the qTD status, or miss signalling occasionally under heavy load.
2823 * If the host machine is too fast, we can miss transaction completion - when
2824 * we scan the active list the transaction still seems to be active. This
2825 * generally exhibits itself as a umass stall that never recovers.
2826 *
2827 * We work around this behaviour by setting up this callback after any softintr
2828 * that completes with transactions still pending, giving us another chance to
2829 * check for completion after the writeback has taken place.
2830 */
2831void
2832ehci_intrlist_timeout(void *arg)
2833{
2834 struct ehci_softc *sc = arg;
2835 int s;
2836
2837 if (sc->sc_bus.dying)
2838 return;
2839
2840 s = splusb()splraise(0x5);
2841 DPRINTFN(1, ("ehci_intrlist_timeout\n"));
2842 usb_schedsoftintr(&sc->sc_bus);
2843 splx(s)spllower(s);
2844}
2845
2846usbd_status
2847ehci_device_ctrl_transfer(struct usbd_xfer *xfer)
2848{
2849 usbd_status err;
2850
2851 /* Insert last in queue. */
2852 err = usb_insert_transfer(xfer);
2853 if (err)
2854 return (err);
2855
2856 /* Pipe isn't running, start first */
2857 return (ehci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue)((&xfer->pipe->queue)->sqh_first)));
2858}
2859
2860usbd_status
2861ehci_device_ctrl_start(struct usbd_xfer *xfer)
2862{
2863 struct ehci_softc *sc = (struct ehci_softc *)xfer->device->bus;
2864 struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
2865 struct ehci_xfer *ex = (struct ehci_xfer *)xfer;
2866 usb_device_request_t *req = &xfer->request;
2867 struct ehci_soft_qtd *setup, *stat, *next;
2868 struct ehci_soft_qh *sqh;
2869 u_int len = UGETW(req->wLength)(*(u_int16_t *)(req->wLength));
2870 usbd_status err;
2871 int s;
2872
2873 KASSERT(xfer->rqflags & URQ_REQUEST)((xfer->rqflags & 0x01) ? (void)0 : __assert("diagnostic "
, "/usr/src/sys/dev/usb/ehci.c", 2873, "xfer->rqflags & URQ_REQUEST"
))
;
2874
2875 if (sc->sc_bus.dying)
2876 return (USBD_IOERROR);
2877
2878 setup = ehci_alloc_sqtd(sc);
2879 if (setup == NULL((void *)0)) {
2880 err = USBD_NOMEM;
2881 goto bad1;
2882 }
2883 stat = ehci_alloc_sqtd(sc);
2884 if (stat == NULL((void *)0)) {
2885 err = USBD_NOMEM;
2886 goto bad2;
2887 }
2888
2889 sqh = epipe->sqh;
2890
2891 /* Set up data transaction */
2892 if (len != 0) {
2893 struct ehci_soft_qtd *end;
2894
2895 err = ehci_alloc_sqtd_chain(sc, len, xfer, &next, &end);
2896 if (err)
2897 goto bad3;
2898 end->qtd.qtd_status &= htole32(~EHCI_QTD_IOC)((__uint32_t)(~0x00008000));
2899 end->nextqtd = stat;
2900 end->qtd.qtd_next =
2901 end->qtd.qtd_altnext = htole32(stat->physaddr)((__uint32_t)(stat->physaddr));
2902 usb_syncmem(&end->dma, end->offs, sizeof(end->qtd),
2903 BUS_DMASYNC_PREWRITE0x04 | BUS_DMASYNC_PREREAD0x01);
2904 } else {
2905 next = stat;
2906 }
2907
2908 memcpy(KERNADDR(&epipe->u.ctl.reqdma, 0), req, sizeof(*req))__builtin_memcpy((((void *)((char *)((&epipe->u.ctl.reqdma
)->block->kaddr + (&epipe->u.ctl.reqdma)->offs
) + (0)))), (req), (sizeof(*req)))
;
2909 usb_syncmem(&epipe->u.ctl.reqdma, 0, sizeof *req, BUS_DMASYNC_PREWRITE0x04);
2910
2911 /* Clear toggle */
2912 setup->qtd.qtd_status = htole32(((__uint32_t)(0x80 | ((0x2) << 8) | ((3) << 10) |
((0) << 31) | ((sizeof(*req)) << 16)))
2913 EHCI_QTD_ACTIVE |((__uint32_t)(0x80 | ((0x2) << 8) | ((3) << 10) |
((0) << 31) | ((sizeof(*req)) << 16)))
2914 EHCI_QTD_SET_PID(EHCI_QTD_PID_SETUP) |((__uint32_t)(0x80 | ((0x2) << 8) | ((3) << 10) |
((0) << 31) | ((sizeof(*req)) << 16)))
2915 EHCI_QTD_SET_CERR(3) |((__uint32_t)(0x80 | ((0x2) << 8) | ((3) << 10) |
((0) << 31) | ((sizeof(*req)) << 16)))
2916 EHCI_QTD_SET_TOGGLE(0) |((__uint32_t)(0x80 | ((0x2) << 8) | ((3) << 10) |
((0) << 31) | ((sizeof(*req)) << 16)))
2917 EHCI_QTD_SET_BYTES(sizeof(*req)))((__uint32_t)(0x80 | ((0x2) << 8) | ((3) << 10) |
((0) << 31) | ((sizeof(*req)) << 16)))
;
2918 setup->qtd.qtd_buffer[0] = htole32(DMAADDR(&epipe->u.ctl.reqdma, 0))((__uint32_t)(((&epipe->u.ctl.reqdma)->block->map
->dm_segs[0].ds_addr + (&epipe->u.ctl.reqdma)->offs
+ (0))))
;
2919 setup->qtd.qtd_buffer_hi[0] = 0;
2920 setup->nextqtd = next;
2921 setup->qtd.qtd_next = setup->qtd.qtd_altnext = htole32(next->physaddr)((__uint32_t)(next->physaddr));
2922 setup->len = sizeof(*req);
2923 usb_syncmem(&setup->dma, setup->offs, sizeof(setup->qtd),
2924 BUS_DMASYNC_PREWRITE0x04 | BUS_DMASYNC_PREREAD0x01);
2925
2926 stat->qtd.qtd_status = htole32(((__uint32_t)(0x80 | ((usbd_xfer_isread(xfer) ? 0x0 : 0x1) <<
8) | ((3) << 10) | ((1) << 31) | 0x00008000))
2927 EHCI_QTD_ACTIVE |((__uint32_t)(0x80 | ((usbd_xfer_isread(xfer) ? 0x0 : 0x1) <<
8) | ((3) << 10) | ((1) << 31) | 0x00008000))
2928 EHCI_QTD_SET_PID(usbd_xfer_isread(xfer) ?((__uint32_t)(0x80 | ((usbd_xfer_isread(xfer) ? 0x0 : 0x1) <<
8) | ((3) << 10) | ((1) << 31) | 0x00008000))
2929 EHCI_QTD_PID_OUT : EHCI_QTD_PID_IN) |((__uint32_t)(0x80 | ((usbd_xfer_isread(xfer) ? 0x0 : 0x1) <<
8) | ((3) << 10) | ((1) << 31) | 0x00008000))
2930 EHCI_QTD_SET_CERR(3) |((__uint32_t)(0x80 | ((usbd_xfer_isread(xfer) ? 0x0 : 0x1) <<
8) | ((3) << 10) | ((1) << 31) | 0x00008000))
2931 EHCI_QTD_SET_TOGGLE(1) |((__uint32_t)(0x80 | ((usbd_xfer_isread(xfer) ? 0x0 : 0x1) <<
8) | ((3) << 10) | ((1) << 31) | 0x00008000))
2932 EHCI_QTD_IOC)((__uint32_t)(0x80 | ((usbd_xfer_isread(xfer) ? 0x0 : 0x1) <<
8) | ((3) << 10) | ((1) << 31) | 0x00008000))
;
2933 stat->qtd.qtd_buffer[0] = 0; /* XXX not needed? */
2934 stat->qtd.qtd_buffer_hi[0] = 0; /* XXX not needed? */
2935 stat->nextqtd = NULL((void *)0);
2936 stat->qtd.qtd_next = stat->qtd.qtd_altnext = htole32(EHCI_LINK_TERMINATE)((__uint32_t)(0x00000001));
2937 stat->len = 0;
2938 usb_syncmem(&stat->dma, stat->offs, sizeof(stat->qtd),
2939 BUS_DMASYNC_PREWRITE0x04 | BUS_DMASYNC_PREREAD0x01);
2940
2941 ex->sqtdstart_TD.sqtd.start = setup;
2942 ex->sqtdend_TD.sqtd.end = stat;
2943#ifdef DIAGNOSTIC1
2944 if (!ex->isdone) {
2945 printf("%s: not done, ex=%p\n", __func__, ex);
2946 }
2947 ex->isdone = 0;
2948#endif
2949
2950 /* Insert qTD in QH list. */
2951 s = splusb()splraise(0x5);
2952 ehci_set_qh_qtd(sqh, setup);
2953 if (xfer->timeout && !sc->sc_bus.use_polling) {
2954 timeout_del(&xfer->timeout_handle);
2955 timeout_set(&xfer->timeout_handle, ehci_timeout, xfer);
2956 timeout_add_msec(&xfer->timeout_handle, xfer->timeout);
2957 }
2958 TAILQ_INSERT_TAIL(&sc->sc_intrhead, ex, inext)do { (ex)->inext.tqe_next = ((void *)0); (ex)->inext.tqe_prev
= (&sc->sc_intrhead)->tqh_last; *(&sc->sc_intrhead
)->tqh_last = (ex); (&sc->sc_intrhead)->tqh_last
= &(ex)->inext.tqe_next; } while (0)
;
2959 xfer->status = USBD_IN_PROGRESS;
2960 splx(s)spllower(s);
2961
2962 return (USBD_IN_PROGRESS);
2963
2964 bad3:
2965 ehci_free_sqtd(sc, stat);
2966 bad2:
2967 ehci_free_sqtd(sc, setup);
2968 bad1:
2969 xfer->status = err;
2970 usb_transfer_complete(xfer);
2971 return (err);
2972}
2973
2974void
2975ehci_device_ctrl_done(struct usbd_xfer *xfer)
2976{
2977 struct ehci_softc *sc = (struct ehci_softc *)xfer->device->bus;
2978 struct ehci_xfer *ex = (struct ehci_xfer *)xfer;
2979
2980 KASSERT(xfer->rqflags & URQ_REQUEST)((xfer->rqflags & 0x01) ? (void)0 : __assert("diagnostic "
, "/usr/src/sys/dev/usb/ehci.c", 2980, "xfer->rqflags & URQ_REQUEST"
))
;
2981
2982 if (xfer->status != USBD_NOMEM) {
2983 ehci_free_sqtd_chain(sc, ex);
2984 }
2985}
2986
2987void
2988ehci_device_ctrl_abort(struct usbd_xfer *xfer)
2989{
2990 ehci_abort_xfer(xfer, USBD_CANCELLED);
2991}
2992
2993void
2994ehci_device_ctrl_close(struct usbd_pipe *pipe)
2995{
2996 ehci_close_pipe(pipe);
2997}
2998
2999usbd_status
3000ehci_device_bulk_transfer(struct usbd_xfer *xfer)
3001{
3002 usbd_status err;
3003
3004 /* Insert last in queue. */
3005 err = usb_insert_transfer(xfer);
3006 if (err)
3007 return (err);
3008
3009 /* Pipe isn't running, start first */
3010 return (ehci_device_bulk_start(SIMPLEQ_FIRST(&xfer->pipe->queue)((&xfer->pipe->queue)->sqh_first)));
3011}
3012
3013usbd_status
3014ehci_device_bulk_start(struct usbd_xfer *xfer)
3015{
3016 struct ehci_softc *sc = (struct ehci_softc *)xfer->device->bus;
3017 struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
3018 struct ehci_xfer *ex = (struct ehci_xfer *)xfer;
3019 struct ehci_soft_qtd *data, *dataend;
3020 struct ehci_soft_qh *sqh;
3021 usbd_status err;
3022 int s;
3023
3024 KASSERT(!(xfer->rqflags & URQ_REQUEST))((!(xfer->rqflags & 0x01)) ? (void)0 : __assert("diagnostic "
, "/usr/src/sys/dev/usb/ehci.c", 3024, "!(xfer->rqflags & URQ_REQUEST)"
))
;
3025
3026 if (sc->sc_bus.dying)
3027 return (USBD_IOERROR);
3028
3029 sqh = epipe->sqh;
3030
3031 err = ehci_alloc_sqtd_chain(sc, xfer->length, xfer, &data, &dataend);
3032 if (err) {
3033 xfer->status = err;
3034 usb_transfer_complete(xfer);
3035 return (err);
3036 }
3037
3038 /* Set up interrupt info. */
3039 ex->sqtdstart_TD.sqtd.start = data;
3040 ex->sqtdend_TD.sqtd.end = dataend;
3041#ifdef DIAGNOSTIC1
3042 if (!ex->isdone) {
3043 printf("ehci_device_bulk_start: not done, ex=%p\n", ex);
3044 }
3045 ex->isdone = 0;
3046#endif
3047
3048 s = splusb()splraise(0x5);
3049 ehci_set_qh_qtd(sqh, data);
3050 if (xfer->timeout && !sc->sc_bus.use_polling) {
3051 timeout_del(&xfer->timeout_handle);
3052 timeout_set(&xfer->timeout_handle, ehci_timeout, xfer);
3053 timeout_add_msec(&xfer->timeout_handle, xfer->timeout);
3054 }
3055 TAILQ_INSERT_TAIL(&sc->sc_intrhead, ex, inext)do { (ex)->inext.tqe_next = ((void *)0); (ex)->inext.tqe_prev
= (&sc->sc_intrhead)->tqh_last; *(&sc->sc_intrhead
)->tqh_last = (ex); (&sc->sc_intrhead)->tqh_last
= &(ex)->inext.tqe_next; } while (0)
;
3056 xfer->status = USBD_IN_PROGRESS;
3057 splx(s)spllower(s);
3058
3059 return (USBD_IN_PROGRESS);
3060}
3061
3062void
3063ehci_device_bulk_abort(struct usbd_xfer *xfer)
3064{
3065 ehci_abort_xfer(xfer, USBD_CANCELLED);
3066}
3067
3068/*
3069 * Close a device bulk pipe.
3070 */
3071void
3072ehci_device_bulk_close(struct usbd_pipe *pipe)
3073{
3074 ehci_close_pipe(pipe);
3075}
3076
3077void
3078ehci_device_bulk_done(struct usbd_xfer *xfer)
3079{
3080 struct ehci_softc *sc = (struct ehci_softc *)xfer->device->bus;
3081 struct ehci_xfer *ex = (struct ehci_xfer *)xfer;
3082
3083 if (xfer->status != USBD_NOMEM) {
3084 ehci_free_sqtd_chain(sc, ex);
3085 }
3086}
3087
3088usbd_status
3089ehci_device_setintr(struct ehci_softc *sc, struct ehci_soft_qh *sqh, int ival)
3090{
3091 struct ehci_soft_islot *isp;
3092 int islot, lev;
3093
3094 /* Find a poll rate that is large enough. */
3095 for (lev = EHCI_IPOLLRATES8 - 1; lev > 0; lev--)
3096 if (EHCI_ILEV_IVAL(lev)(1 << (lev)) <= ival)
3097 break;
3098
3099 /* Pick an interrupt slot at the right level. */
3100 /* XXX could do better than picking at random */
3101 islot = EHCI_IQHIDX(lev, arc4random())((((arc4random()) & ((1 << (lev)) - 1)) | (1 <<
(lev))) - 1)
;
3102
3103 sqh->islot = islot;
3104 isp = &sc->sc_islots[islot];
3105 ehci_add_qh(sqh, isp->sqh);
3106
3107 return (USBD_NORMAL_COMPLETION);
3108}
3109
3110usbd_status
3111ehci_device_intr_transfer(struct usbd_xfer *xfer)
3112{
3113 usbd_status err;
3114
3115 /* Insert last in queue. */
3116 err = usb_insert_transfer(xfer);
3117 if (err)
3118 return (err);
3119
3120 /*
3121 * Pipe isn't running (otherwise err would be USBD_INPROG),
3122 * so start it first.
3123 */
3124 return (ehci_device_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue)((&xfer->pipe->queue)->sqh_first)));
3125}
3126
3127usbd_status
3128ehci_device_intr_start(struct usbd_xfer *xfer)
3129{
3130 struct ehci_softc *sc = (struct ehci_softc *)xfer->device->bus;
3131 struct ehci_xfer *ex = (struct ehci_xfer *)xfer;
3132 struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
3133 struct ehci_soft_qtd *data, *dataend;
3134 struct ehci_soft_qh *sqh;
3135 usbd_status err;
3136 int s;
3137
3138 KASSERT(!(xfer->rqflags & URQ_REQUEST))((!(xfer->rqflags & 0x01)) ? (void)0 : __assert("diagnostic "
, "/usr/src/sys/dev/usb/ehci.c", 3138, "!(xfer->rqflags & URQ_REQUEST)"
))
;
3139
3140 if (sc->sc_bus.dying)
3141 return (USBD_IOERROR);
3142
3143 sqh = epipe->sqh;
3144
3145 err = ehci_alloc_sqtd_chain(sc, xfer->length, xfer, &data, &dataend);
3146 if (err) {
3147 xfer->status = err;
3148 usb_transfer_complete(xfer);
3149 return (err);
3150 }
3151
3152 /* Set up interrupt info. */
3153 ex->sqtdstart_TD.sqtd.start = data;
3154 ex->sqtdend_TD.sqtd.end = dataend;
3155#ifdef DIAGNOSTIC1
3156 if (!ex->isdone)
3157 printf("ehci_device_intr_start: not done, ex=%p\n", ex);
3158 ex->isdone = 0;
3159#endif
3160
3161 s = splusb()splraise(0x5);
3162 ehci_set_qh_qtd(sqh, data);
3163 if (xfer->timeout && !sc->sc_bus.use_polling) {
3164 timeout_del(&xfer->timeout_handle);
3165 timeout_set(&xfer->timeout_handle, ehci_timeout, xfer);
3166 timeout_add_msec(&xfer->timeout_handle, xfer->timeout);
3167 }
3168 TAILQ_INSERT_TAIL(&sc->sc_intrhead, ex, inext)do { (ex)->inext.tqe_next = ((void *)0); (ex)->inext.tqe_prev
= (&sc->sc_intrhead)->tqh_last; *(&sc->sc_intrhead
)->tqh_last = (ex); (&sc->sc_intrhead)->tqh_last
= &(ex)->inext.tqe_next; } while (0)
;
3169 xfer->status = USBD_IN_PROGRESS;
3170 splx(s)spllower(s);
3171
3172 return (USBD_IN_PROGRESS);
3173}
3174
3175void
3176ehci_device_intr_abort(struct usbd_xfer *xfer)
3177{
3178 KASSERT(!xfer->pipe->repeat || xfer->pipe->intrxfer == xfer)((!xfer->pipe->repeat || xfer->pipe->intrxfer == xfer
) ? (void)0 : __assert("diagnostic ", "/usr/src/sys/dev/usb/ehci.c"
, 3178, "!xfer->pipe->repeat || xfer->pipe->intrxfer == xfer"
))
;
3179
3180 /*
3181 * XXX - abort_xfer uses ehci_sync_hc, which syncs via the advance
3182 * async doorbell. That's dependant on the async list, whereas
3183 * intr xfers are periodic, should not use this?
3184 */
3185 ehci_abort_xfer(xfer, USBD_CANCELLED);
3186}
3187
3188void
3189ehci_device_intr_close(struct usbd_pipe *pipe)
3190{
3191 ehci_close_pipe(pipe);
3192}
3193
3194void
3195ehci_device_intr_done(struct usbd_xfer *xfer)
3196{
3197 struct ehci_softc *sc = (struct ehci_softc *)xfer->device->bus;
3198 struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
3199 struct ehci_xfer *ex = (struct ehci_xfer *)xfer;
3200 struct ehci_soft_qtd *data, *dataend;
3201 struct ehci_soft_qh *sqh;
3202 usbd_status err;
3203 int s;
3204
3205 if (xfer->pipe->repeat) {
3206 ehci_free_sqtd_chain(sc, ex);
3207
3208 sqh = epipe->sqh;
3209
3210 err = ehci_alloc_sqtd_chain(sc, xfer->length, xfer, &data, &dataend);
3211 if (err) {
3212 xfer->status = err;
3213 return;
3214 }
3215
3216 /* Set up interrupt info. */
3217 ex->sqtdstart_TD.sqtd.start = data;
3218 ex->sqtdend_TD.sqtd.end = dataend;
3219#ifdef DIAGNOSTIC1
3220 if (!ex->isdone) {
3221 printf("ehci_device_intr_done: not done, ex=%p\n",
3222 ex);
3223 }
3224 ex->isdone = 0;
3225#endif
3226
3227 s = splusb()splraise(0x5);
3228 ehci_set_qh_qtd(sqh, data);
3229 if (xfer->timeout && !sc->sc_bus.use_polling) {
3230 timeout_del(&xfer->timeout_handle);
3231 timeout_set(&xfer->timeout_handle, ehci_timeout, xfer);
3232 timeout_add_msec(&xfer->timeout_handle, xfer->timeout);
3233 }
3234 TAILQ_INSERT_TAIL(&sc->sc_intrhead, ex, inext)do { (ex)->inext.tqe_next = ((void *)0); (ex)->inext.tqe_prev
= (&sc->sc_intrhead)->tqh_last; *(&sc->sc_intrhead
)->tqh_last = (ex); (&sc->sc_intrhead)->tqh_last
= &(ex)->inext.tqe_next; } while (0)
;
3235 xfer->status = USBD_IN_PROGRESS;
3236 splx(s)spllower(s);
3237 } else if (xfer->status != USBD_NOMEM) {
3238 ehci_free_sqtd_chain(sc, ex);
3239 }
3240}
3241
3242usbd_status
3243ehci_device_isoc_transfer(struct usbd_xfer *xfer)
3244{
3245 usbd_status err;
3246
3247 err = usb_insert_transfer(xfer);
3248 if (err && err != USBD_IN_PROGRESS)
3249 return (err);
3250
3251 return (ehci_device_isoc_start(xfer));
3252}
3253
3254usbd_status
3255ehci_device_isoc_start(struct usbd_xfer *xfer)
3256{
3257 struct ehci_softc *sc = (struct ehci_softc *)xfer->device->bus;
3258 struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
3259 struct ehci_xfer *ex = (struct ehci_xfer *)xfer;
3260 usb_endpoint_descriptor_t *ed = xfer->pipe->endpoint->edesc;
3261 uint8_t ival = ed->bInterval;
3262 struct ehci_soft_itd *itd;
3263 int s, frindex;
3264 uint32_t link;
3265
3266 KASSERT(!(xfer->rqflags & URQ_REQUEST))((!(xfer->rqflags & 0x01)) ? (void)0 : __assert("diagnostic "
, "/usr/src/sys/dev/usb/ehci.c", 3266, "!(xfer->rqflags & URQ_REQUEST)"
))
;
3267 KASSERT(ival > 0 && ival <= 16)((ival > 0 && ival <= 16) ? (void)0 : __assert(
"diagnostic ", "/usr/src/sys/dev/usb/ehci.c", 3267, "ival > 0 && ival <= 16"
))
;
3268
3269 /*
3270 * To allow continuous transfers, above we start all transfers
3271 * immediately. However, we're still going to get usbd_start_next call
3272 * this when another xfer completes. So, check if this is already
3273 * in progress or not
3274 */
3275 if (ex->itdstart_TD.itd.start != NULL((void *)0))
3276 return (USBD_IN_PROGRESS);
3277
3278 if (sc->sc_bus.dying)
3279 return (USBD_IOERROR);
3280
3281 /* Why would you do that anyway? */
3282 if (sc->sc_bus.use_polling)
3283 return (USBD_INVAL);
3284
3285 /*
3286 * To avoid complication, don't allow a request right now that'll span
3287 * the entire frame table. To within 4 frames, to allow some leeway
3288 * on either side of where the hc currently is.
3289 */
3290 if ((1 << (ival - 1)) * xfer->nframes >= (sc->sc_flsize - 4) * 8)
3291 return (USBD_INVAL);
3292
3293 /*
3294 * Step 1: Allocate and initialize itds.
3295 */
3296 if (xfer->device->speed == USB_SPEED_HIGH3) {
3297 if (ehci_alloc_itd_chain(sc, xfer))
3298 return (USBD_INVAL);
3299
3300 link = EHCI_LINK_ITD0x0;
3301 } else {
3302 if (ehci_alloc_sitd_chain(sc, xfer))
3303 return (USBD_INVAL);
3304
3305 link = EHCI_LINK_SITD0x4;
3306 }
3307
3308#ifdef DIAGNOSTIC1
3309 if (!ex->isdone) {
3310 printf("%s: not done, ex=%p\n", __func__, ex);
3311 }
3312 ex->isdone = 0;
3313#endif
3314
3315 /*
3316 * Part 2: Transfer descriptors have now been set up, now they must
3317 * be scheduled into the period frame list. Erk. Not wanting to
3318 * complicate matters, transfer is denied if the transfer spans
3319 * more than the period frame list.
3320 */
3321 s = splusb()splraise(0x5);
3322
3323 /* Start inserting frames */
3324 if (epipe->u.isoc.cur_xfers > 0) {
3325 frindex = epipe->u.isoc.next_frame;
3326 } else {
3327 frindex = EOREAD4(sc, EHCI_FRINDEX)(((sc)->iot)->read_4(((sc)->ioh), ((sc)->sc_offs+
(0x0c))))
;
3328 frindex = frindex >> 3; /* Erase microframe index */
3329 frindex += 2;
3330 }
3331
3332 if (frindex >= sc->sc_flsize)
3333 frindex &= (sc->sc_flsize - 1);
3334
3335 /* What's the frame interval? */
3336 ival = (1 << (ival - 1));
3337 if (ival / 8 == 0)
3338 ival = 1;
3339 else
3340 ival /= 8;
3341
3342 /* Abuse the fact that itd_next == sitd_next. */
3343 for (itd = ex->itdstart_TD.itd.start; itd != NULL((void *)0); itd = itd->xfer_next) {
3344 itd->itd.itd_next = sc->sc_flist[frindex];
3345 if (itd->itd.itd_next == 0)
3346 itd->itd.itd_next = htole32(EHCI_LINK_TERMINATE)((__uint32_t)(0x00000001));
3347
3348 sc->sc_flist[frindex] = htole32(link | itd->physaddr)((__uint32_t)(link | itd->physaddr));
3349 itd->u.frame_list.next = sc->sc_softitds[frindex];
3350 sc->sc_softitds[frindex] = itd;
3351 if (itd->u.frame_list.next != NULL((void *)0))
3352 itd->u.frame_list.next->u.frame_list.prev = itd;
3353 itd->slot = frindex;
3354 itd->u.frame_list.prev = NULL((void *)0);
3355
3356 frindex += ival;
3357 if (frindex >= sc->sc_flsize)
3358 frindex -= sc->sc_flsize;
3359 }
3360
3361 epipe->u.isoc.cur_xfers++;
3362 epipe->u.isoc.next_frame = frindex;
3363
3364 TAILQ_INSERT_TAIL(&sc->sc_intrhead, ex, inext)do { (ex)->inext.tqe_next = ((void *)0); (ex)->inext.tqe_prev
= (&sc->sc_intrhead)->tqh_last; *(&sc->sc_intrhead
)->tqh_last = (ex); (&sc->sc_intrhead)->tqh_last
= &(ex)->inext.tqe_next; } while (0)
;
3365 xfer->status = USBD_IN_PROGRESS;
3366 xfer->done = 0;
3367 splx(s)spllower(s);
3368
3369 return (USBD_IN_PROGRESS);
3370}
3371
3372int
3373ehci_alloc_itd_chain(struct ehci_softc *sc, struct usbd_xfer *xfer)
3374{
3375 struct ehci_xfer *ex = (struct ehci_xfer *)xfer;
3376 usb_endpoint_descriptor_t *ed = xfer->pipe->endpoint->edesc;
3377 const uint32_t mps = UGETW(ed->wMaxPacketSize)(*(u_int16_t *)(ed->wMaxPacketSize));
3378 struct ehci_soft_itd *itd = NULL((void *)0), *pitd = NULL((void *)0);
3379 int i, j, nframes, uframes, ufrperframe;
3380 int offs = 0, trans_count = 0;
3381
3382 /*
3383 * How many itds do we need? One per transfer if interval >= 8
3384 * microframes, fewer if we use multiple microframes per frame.
3385 */
3386 switch (ed->bInterval) {
3387 case 1:
3388 ufrperframe = 8;
3389 break;
3390 case 2:
3391 ufrperframe = 4;
3392 break;
3393 case 3:
3394 ufrperframe = 2;
3395 break;
3396 default:
3397 ufrperframe = 1;
3398 break;
3399 }
3400 nframes = (xfer->nframes + (ufrperframe - 1)) / ufrperframe;
3401 uframes = 8 / ufrperframe;
3402 if (nframes == 0)
3403 return (1);
3404
3405 usb_syncmem(&xfer->dmabuf, 0, xfer->length,
3406 usbd_xfer_isread(xfer) ?
3407 BUS_DMASYNC_PREREAD0x01 : BUS_DMASYNC_PREWRITE0x04);
3408 for (i = 0; i < nframes; i++) {
3409 uint32_t froffs = offs;
3410
3411 itd = ehci_alloc_itd(sc);
3412 if (itd == NULL((void *)0)) {
3413 ehci_free_itd_chain(sc, ex);
3414 return (1);
3415 }
3416
3417 if (pitd != NULL((void *)0))
3418 pitd->xfer_next = itd;
3419 else
3420 ex->itdstart_TD.itd.start = itd;
3421
3422 /*
3423 * Step 1.5, initialize uframes
3424 */
3425 for (j = 0; j < 8; j += uframes) {
3426 /* Calculate which page in the list this starts in */
3427 int addr = DMAADDR(&xfer->dmabuf, froffs)((&xfer->dmabuf)->block->map->dm_segs[0].ds_addr
+ (&xfer->dmabuf)->offs + (froffs))
;
3428 addr = EHCI_PAGE_OFFSET(addr)((addr) & 0xfff) + (offs - froffs);
3429 addr = EHCI_PAGE(addr)((addr) &~ 0xfff) / EHCI_PAGE_SIZE0x1000;
3430
3431 /* This gets the initial offset into the first page,
3432 * looks how far further along the current uframe
3433 * offset is. Works out how many pages that is.
3434 */
3435 itd->itd.itd_ctl[j] = htole32(((__uint32_t)(0x80000000 | (((xfer->frlengths[trans_count]
) & 0xfff) << 16) | (((addr) & 0x7) << 12
) | (((((&xfer->dmabuf)->block->map->dm_segs[
0].ds_addr + (&xfer->dmabuf)->offs + (offs))) &
0xfff) << 0)))
3436 EHCI_ITD_ACTIVE |((__uint32_t)(0x80000000 | (((xfer->frlengths[trans_count]
) & 0xfff) << 16) | (((addr) & 0x7) << 12
) | (((((&xfer->dmabuf)->block->map->dm_segs[
0].ds_addr + (&xfer->dmabuf)->offs + (offs))) &
0xfff) << 0)))
3437 EHCI_ITD_SET_LEN(xfer->frlengths[trans_count]) |((__uint32_t)(0x80000000 | (((xfer->frlengths[trans_count]
) & 0xfff) << 16) | (((addr) & 0x7) << 12
) | (((((&xfer->dmabuf)->block->map->dm_segs[
0].ds_addr + (&xfer->dmabuf)->offs + (offs))) &
0xfff) << 0)))
3438 EHCI_ITD_SET_PG(addr) |((__uint32_t)(0x80000000 | (((xfer->frlengths[trans_count]
) & 0xfff) << 16) | (((addr) & 0x7) << 12
) | (((((&xfer->dmabuf)->block->map->dm_segs[
0].ds_addr + (&xfer->dmabuf)->offs + (offs))) &
0xfff) << 0)))
3439 EHCI_ITD_SET_OFFS(DMAADDR(&xfer->dmabuf, offs))((__uint32_t)(0x80000000 | (((xfer->frlengths[trans_count]
) & 0xfff) << 16) | (((addr) & 0x7) << 12
) | (((((&xfer->dmabuf)->block->map->dm_segs[
0].ds_addr + (&xfer->dmabuf)->offs + (offs))) &
0xfff) << 0)))
3440 )((__uint32_t)(0x80000000 | (((xfer->frlengths[trans_count]
) & 0xfff) << 16) | (((addr) & 0x7) << 12
) | (((((&xfer->dmabuf)->block->map->dm_segs[
0].ds_addr + (&xfer->dmabuf)->offs + (offs))) &
0xfff) << 0)))
;
3441
3442 offs += xfer->frlengths[trans_count];
3443 trans_count++;
3444
3445 if (trans_count >= xfer->nframes) { /*Set IOC*/
3446 itd->itd.itd_ctl[j] |= htole32(EHCI_ITD_IOC)((__uint32_t)(0x8000));
3447 break;
3448 }
3449 }
3450
3451 /* Step 1.75, set buffer pointers. To simplify matters, all
3452 * pointers are filled out for the next 7 hardware pages in
3453 * the dma block, so no need to worry what pages to cover
3454 * and what to not.
3455 */
3456
3457 for (j = 0; j < 7; j++) {
3458 /*
3459 * Don't try to lookup a page that's past the end
3460 * of buffer
3461 */
3462 int page_offs = EHCI_PAGE(froffs +((froffs + (0x1000 * j)) &~ 0xfff)
3463 (EHCI_PAGE_SIZE * j))((froffs + (0x1000 * j)) &~ 0xfff);
3464
3465 if (page_offs >= xfer->dmabuf.block->size)
3466 break;
3467
3468 long long page = DMAADDR(&xfer->dmabuf, page_offs)((&xfer->dmabuf)->block->map->dm_segs[0].ds_addr
+ (&xfer->dmabuf)->offs + (page_offs))
;
3469 page = EHCI_PAGE(page)((page) &~ 0xfff);
3470 itd->itd.itd_bufr[j] = htole32(page)((__uint32_t)(page));
3471 itd->itd.itd_bufr_hi[j] = htole32(page >> 32)((__uint32_t)(page >> 32));
3472 }
3473
3474 /*
3475 * Other special values
3476 */
3477 itd->itd.itd_bufr[0] |= htole32(((__uint32_t)((((((ed->bEndpointAddress) & 0x0f)) &
0xf) << 8) | ((xfer->pipe->device->address) &
0x7f)))
3478 EHCI_ITD_SET_ENDPT(UE_GET_ADDR(ed->bEndpointAddress)) |((__uint32_t)((((((ed->bEndpointAddress) & 0x0f)) &
0xf) << 8) | ((xfer->pipe->device->address) &
0x7f)))
3479 EHCI_ITD_SET_DADDR(xfer->pipe->device->address)((__uint32_t)((((((ed->bEndpointAddress) & 0x0f)) &
0xf) << 8) | ((xfer->pipe->device->address) &
0x7f)))
3480 )((__uint32_t)((((((ed->bEndpointAddress) & 0x0f)) &
0xf) << 8) | ((xfer->pipe->device->address) &
0x7f)))
;
3481
3482 itd->itd.itd_bufr[1] |= htole32(((__uint32_t)((usbd_xfer_isread(xfer) ? (((1) & 1) <<
11) : 0) | ((((mps) & 0x7ff)) & 0x7ff)))
3483 (usbd_xfer_isread(xfer) ? EHCI_ITD_SET_DIR(1) : 0) |((__uint32_t)((usbd_xfer_isread(xfer) ? (((1) & 1) <<
11) : 0) | ((((mps) & 0x7ff)) & 0x7ff)))
3484 EHCI_ITD_SET_MAXPKT(UE_GET_SIZE(mps))((__uint32_t)((usbd_xfer_isread(xfer) ? (((1) & 1) <<
11) : 0) | ((((mps) & 0x7ff)) & 0x7ff)))
3485 )((__uint32_t)((usbd_xfer_isread(xfer) ? (((1) & 1) <<
11) : 0) | ((((mps) & 0x7ff)) & 0x7ff)))
;
3486 /* FIXME: handle invalid trans */
3487 itd->itd.itd_bufr[2] |= htole32(((__uint32_t)((((((mps) >> 11) & 0x3)+1) & 0x3)
))
3488 EHCI_ITD_SET_MULTI(UE_GET_TRANS(mps)+1)((__uint32_t)((((((mps) >> 11) & 0x3)+1) & 0x3)
))
3489 )((__uint32_t)((((((mps) >> 11) & 0x3)+1) & 0x3)
))
;
3490
3491 pitd = itd;
3492 }
3493
3494 ex->itdend_TD.itd.end = itd;
3495
3496 return (0);
3497}
3498
3499int
3500ehci_alloc_sitd_chain(struct ehci_softc *sc, struct usbd_xfer *xfer)
3501{
3502 struct ehci_xfer *ex = (struct ehci_xfer *)xfer;
3503 struct usbd_device *hshub = xfer->device->myhsport->parent;
3504 usb_endpoint_descriptor_t *ed = xfer->pipe->endpoint->edesc;
3505 struct ehci_soft_itd *itd = NULL((void *)0), *pitd = NULL((void *)0);
3506 uint8_t smask, cmask, tp, uf;
3507 int i, nframes, offs = 0;
3508 uint32_t endp;
3509
3510 nframes = xfer->nframes;
3511 if (nframes == 0)
3512 return (1);
3513
3514 endp = EHCI_SITD_SET_ENDPT(UE_GET_ADDR(ed->bEndpointAddress))((((ed->bEndpointAddress) & 0x0f)) << 8) |
3515 EHCI_SITD_SET_ADDR(xfer->device->address)(xfer->device->address) |
3516 EHCI_SITD_SET_PORT(xfer->device->myhsport->portno)((xfer->device->myhsport->portno) << 23) |
3517 EHCI_SITD_SET_HUBA(hshub->address)((hshub->address) << 16);
3518
3519 if (usbd_xfer_isread(xfer))
3520 endp |= EHCI_SITD_SET_DIR(1)((1) << 31);
3521
3522 usb_syncmem(&xfer->dmabuf, 0, xfer->length,
3523 usbd_xfer_isread(xfer) ?
3524 BUS_DMASYNC_PREREAD0x01 : BUS_DMASYNC_PREWRITE0x04);
3525 for (i = 0; i < nframes; i++) {
3526 uint32_t addr = DMAADDR(&xfer->dmabuf, offs)((&xfer->dmabuf)->block->map->dm_segs[0].ds_addr
+ (&xfer->dmabuf)->offs + (offs))
;
3527 uint32_t page = EHCI_PAGE(addr + xfer->frlengths[i] - 1)((addr + xfer->frlengths[i] - 1) &~ 0xfff);
3528
3529 itd = ehci_alloc_itd(sc);
3530 if (itd == NULL((void *)0)) {
3531 ehci_free_itd_chain(sc, ex);
3532 return (1);
3533 }
3534 if (pitd)
3535 pitd->xfer_next = itd;
3536 else
3537 ex->itdstart_TD.itd.start = itd;
3538
3539 itd->sitd.sitd_endp = htole32(endp)((__uint32_t)(endp));
3540 itd->sitd.sitd_back = htole32(EHCI_LINK_TERMINATE)((__uint32_t)(0x00000001));
3541 itd->sitd.sitd_trans = htole32(((__uint32_t)(0x80 | (((xfer->frlengths[i]) & 0x3ff) <<
16) | ((i == nframes - 1) ? 0x80000000 : 0)))
3542 EHCI_SITD_ACTIVE |((__uint32_t)(0x80 | (((xfer->frlengths[i]) & 0x3ff) <<
16) | ((i == nframes - 1) ? 0x80000000 : 0)))
3543 EHCI_SITD_SET_LEN(xfer->frlengths[i]) |((__uint32_t)(0x80 | (((xfer->frlengths[i]) & 0x3ff) <<
16) | ((i == nframes - 1) ? 0x80000000 : 0)))
3544 ((i == nframes - 1) ? EHCI_SITD_IOC : 0)((__uint32_t)(0x80 | (((xfer->frlengths[i]) & 0x3ff) <<
16) | ((i == nframes - 1) ? 0x80000000 : 0)))
3545 )((__uint32_t)(0x80 | (((xfer->frlengths[i]) & 0x3ff) <<
16) | ((i == nframes - 1) ? 0x80000000 : 0)))
;
3546
3547 uf = max(1, ((xfer->frlengths[i] + 187) / 188));
3548
3549 /*
3550 * Since we do not yet budget and schedule micro-frames
3551 * we assume there is no other transfer using the same
3552 * TT.
3553 */
3554 if (usbd_xfer_isread(xfer)) {
3555 smask = 0x01;
3556 cmask = ((1 << (uf + 2)) - 1) << 2;
3557 } else {
3558 /* Is the payload is greater than 188 bytes? */
3559 if (uf == 1)
3560 tp = EHCI_SITD_TP_ALL0x0;
3561 else
3562 tp = EHCI_SITD_TP_BEGIN0x1;
3563
3564 page |= EHCI_SITD_SET_TCOUNT(uf)((uf) << 0) | EHCI_SITD_SET_TP(tp)((tp) << 3);
3565 smask = (1 << uf) - 1;
3566 cmask = 0x00;
3567 }
3568
3569 itd->sitd.sitd_sched = htole32(((__uint32_t)(((smask) << 0) | ((cmask) << 8)))
3570 EHCI_SITD_SET_SMASK(smask) | EHCI_SITD_SET_CMASK(cmask)((__uint32_t)(((smask) << 0) | ((cmask) << 8)))
3571 )((__uint32_t)(((smask) << 0) | ((cmask) << 8)));
3572 itd->sitd.sitd_bufr[0] = htole32(addr)((__uint32_t)(addr));
3573 itd->sitd.sitd_bufr[1] = htole32(page)((__uint32_t)(page));
3574
3575 offs += xfer->frlengths[i];
3576 pitd = itd;
3577 }
3578
3579 ex->itdend_TD.itd.end = itd;
3580
3581 return (0);
3582}
3583
3584void
3585ehci_device_isoc_abort(struct usbd_xfer *xfer)
3586{
3587 int s;
3588
3589 s = splusb()splraise(0x5);
3590 ehci_abort_isoc_xfer(xfer, USBD_CANCELLED);
3591 splx(s)spllower(s);
3592}
3593
3594void
3595ehci_device_isoc_close(struct usbd_pipe *pipe)
3596{
3597}
3598
3599void
3600ehci_device_isoc_done(struct usbd_xfer *xfer)
3601{
3602 struct ehci_softc *sc = (struct ehci_softc *)xfer->device->bus;
3603 struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
3604 struct ehci_xfer *ex = (struct ehci_xfer *)xfer;
3605 int s;
3606
3607 s = splusb()splraise(0x5);
3608 epipe->u.isoc.cur_xfers--;
3609 if (xfer->status != USBD_NOMEM) {
3610 ehci_rem_itd_chain(sc, ex);
3611 ehci_free_itd_chain(sc, ex);
3612 }
3613 splx(s)spllower(s);
3614}