uhci.c revision 1.289 1 /* $NetBSD: uhci.c,v 1.289 2020/02/12 16:01:00 riastradh Exp $ */
2
3 /*
4 * Copyright (c) 1998, 2004, 2011, 2012 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Lennart Augustsson (lennart (at) augustsson.net) at
9 * Carlstedt Research & Technology, Jared D. McNeill (jmcneill (at) invisible.ca)
10 * and Matthew R. Green (mrg (at) eterna.com.au).
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 /*
35 * USB Universal Host Controller driver.
36 * Handles e.g. PIIX3 and PIIX4.
37 *
38 * UHCI spec: http://www.intel.com/technology/usb/spec.htm
39 * USB spec: http://www.usb.org/developers/docs/
40 * PIIXn spec: ftp://download.intel.com/design/intarch/datashts/29055002.pdf
41 * ftp://download.intel.com/design/intarch/datashts/29056201.pdf
42 */
43
44 #include <sys/cdefs.h>
45 __KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.289 2020/02/12 16:01:00 riastradh Exp $");
46
47 #ifdef _KERNEL_OPT
48 #include "opt_usb.h"
49 #endif
50
51 #include <sys/param.h>
52
53 #include <sys/bus.h>
54 #include <sys/cpu.h>
55 #include <sys/device.h>
56 #include <sys/kernel.h>
57 #include <sys/kmem.h>
58 #include <sys/mutex.h>
59 #include <sys/proc.h>
60 #include <sys/queue.h>
61 #include <sys/select.h>
62 #include <sys/sysctl.h>
63 #include <sys/systm.h>
64
65 #include <machine/endian.h>
66
67 #include <dev/usb/usb.h>
68 #include <dev/usb/usbdi.h>
69 #include <dev/usb/usbdivar.h>
70 #include <dev/usb/usb_mem.h>
71
72 #include <dev/usb/uhcireg.h>
73 #include <dev/usb/uhcivar.h>
74 #include <dev/usb/usbroothub.h>
75 #include <dev/usb/usbhist.h>
76
77 /* Use bandwidth reclamation for control transfers. Some devices choke on it. */
78 /*#define UHCI_CTL_LOOP */
79
80 #ifdef UHCI_DEBUG
81 uhci_softc_t *thesc;
82 int uhcinoloop = 0;
83 #endif
84
85 #ifdef USB_DEBUG
86 #ifndef UHCI_DEBUG
87 #define uhcidebug 0
88 #else
89 static int uhcidebug = 0;
90
91 SYSCTL_SETUP(sysctl_hw_uhci_setup, "sysctl hw.uhci setup")
92 {
93 int err;
94 const struct sysctlnode *rnode;
95 const struct sysctlnode *cnode;
96
97 err = sysctl_createv(clog, 0, NULL, &rnode,
98 CTLFLAG_PERMANENT, CTLTYPE_NODE, "uhci",
99 SYSCTL_DESCR("uhci global controls"),
100 NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL);
101
102 if (err)
103 goto fail;
104
105 /* control debugging printfs */
106 err = sysctl_createv(clog, 0, &rnode, &cnode,
107 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
108 "debug", SYSCTL_DESCR("Enable debugging output"),
109 NULL, 0, &uhcidebug, sizeof(uhcidebug), CTL_CREATE, CTL_EOL);
110 if (err)
111 goto fail;
112
113 return;
114 fail:
115 aprint_error("%s: sysctl_createv failed (err = %d)\n", __func__, err);
116 }
117
118 #endif /* UHCI_DEBUG */
119 #endif /* USB_DEBUG */
120
121 #define DPRINTF(FMT,A,B,C,D) USBHIST_LOGN(uhcidebug,1,FMT,A,B,C,D)
122 #define DPRINTFN(N,FMT,A,B,C,D) USBHIST_LOGN(uhcidebug,N,FMT,A,B,C,D)
123 #define UHCIHIST_FUNC() USBHIST_FUNC()
124 #define UHCIHIST_CALLED(name) USBHIST_CALLED(uhcidebug)
125
126 /*
127 * The UHCI controller is little endian, so on big endian machines
128 * the data stored in memory needs to be swapped.
129 */
130
131 struct uhci_pipe {
132 struct usbd_pipe pipe;
133 int nexttoggle;
134
135 u_char aborting;
136 struct usbd_xfer *abortstart, abortend;
137
138 /* Info needed for different pipe kinds. */
139 union {
140 /* Control pipe */
141 struct {
142 uhci_soft_qh_t *sqh;
143 usb_dma_t reqdma;
144 uhci_soft_td_t *setup;
145 uhci_soft_td_t *stat;
146 } ctrl;
147 /* Interrupt pipe */
148 struct {
149 int npoll;
150 uhci_soft_qh_t **qhs;
151 } intr;
152 /* Bulk pipe */
153 struct {
154 uhci_soft_qh_t *sqh;
155 } bulk;
156 /* Isochronous pipe */
157 struct isoc {
158 uhci_soft_td_t **stds;
159 int next, inuse;
160 } isoc;
161 };
162 };
163
164 typedef TAILQ_HEAD(ux_completeq, uhci_xfer) ux_completeq_t;
165
166 Static void uhci_globalreset(uhci_softc_t *);
167 Static usbd_status uhci_portreset(uhci_softc_t*, int);
168 Static void uhci_reset(uhci_softc_t *);
169 Static usbd_status uhci_run(uhci_softc_t *, int, int);
170 Static uhci_soft_td_t *uhci_alloc_std(uhci_softc_t *);
171 Static void uhci_free_std(uhci_softc_t *, uhci_soft_td_t *);
172 Static void uhci_free_std_locked(uhci_softc_t *, uhci_soft_td_t *);
173 Static uhci_soft_qh_t *uhci_alloc_sqh(uhci_softc_t *);
174 Static void uhci_free_sqh(uhci_softc_t *, uhci_soft_qh_t *);
175 #if 0
176 Static void uhci_enter_ctl_q(uhci_softc_t *, uhci_soft_qh_t *,
177 uhci_intr_info_t *);
178 Static void uhci_exit_ctl_q(uhci_softc_t *, uhci_soft_qh_t *);
179 #endif
180
181 #if 0
182 Static void uhci_free_std_chain(uhci_softc_t *, uhci_soft_td_t *,
183 uhci_soft_td_t *);
184 #endif
185 Static int uhci_alloc_std_chain(uhci_softc_t *, struct usbd_xfer *,
186 int, int, uhci_soft_td_t **);
187 Static void uhci_free_stds(uhci_softc_t *, struct uhci_xfer *);
188
189 Static void uhci_reset_std_chain(uhci_softc_t *, struct usbd_xfer *,
190 int, int, int *, uhci_soft_td_t **);
191
192 Static void uhci_poll_hub(void *);
193 Static void uhci_check_intr(uhci_softc_t *, struct uhci_xfer *,
194 ux_completeq_t *);
195 Static void uhci_idone(struct uhci_xfer *, ux_completeq_t *);
196
197 Static void uhci_abortx(struct usbd_xfer *);
198
199 Static void uhci_add_ls_ctrl(uhci_softc_t *, uhci_soft_qh_t *);
200 Static void uhci_add_hs_ctrl(uhci_softc_t *, uhci_soft_qh_t *);
201 Static void uhci_add_bulk(uhci_softc_t *, uhci_soft_qh_t *);
202 Static void uhci_remove_ls_ctrl(uhci_softc_t *,uhci_soft_qh_t *);
203 Static void uhci_remove_hs_ctrl(uhci_softc_t *,uhci_soft_qh_t *);
204 Static void uhci_remove_bulk(uhci_softc_t *,uhci_soft_qh_t *);
205 Static void uhci_add_loop(uhci_softc_t *);
206 Static void uhci_rem_loop(uhci_softc_t *);
207
208 Static usbd_status uhci_setup_isoc(struct usbd_pipe *);
209
210 Static struct usbd_xfer *
211 uhci_allocx(struct usbd_bus *, unsigned int);
212 Static void uhci_freex(struct usbd_bus *, struct usbd_xfer *);
213 Static bool uhci_dying(struct usbd_bus *);
214 Static void uhci_get_lock(struct usbd_bus *, kmutex_t **);
215 Static int uhci_roothub_ctrl(struct usbd_bus *,
216 usb_device_request_t *, void *, int);
217
218 Static int uhci_device_ctrl_init(struct usbd_xfer *);
219 Static void uhci_device_ctrl_fini(struct usbd_xfer *);
220 Static usbd_status uhci_device_ctrl_transfer(struct usbd_xfer *);
221 Static usbd_status uhci_device_ctrl_start(struct usbd_xfer *);
222 Static void uhci_device_ctrl_abort(struct usbd_xfer *);
223 Static void uhci_device_ctrl_close(struct usbd_pipe *);
224 Static void uhci_device_ctrl_done(struct usbd_xfer *);
225
226 Static int uhci_device_intr_init(struct usbd_xfer *);
227 Static void uhci_device_intr_fini(struct usbd_xfer *);
228 Static usbd_status uhci_device_intr_transfer(struct usbd_xfer *);
229 Static usbd_status uhci_device_intr_start(struct usbd_xfer *);
230 Static void uhci_device_intr_abort(struct usbd_xfer *);
231 Static void uhci_device_intr_close(struct usbd_pipe *);
232 Static void uhci_device_intr_done(struct usbd_xfer *);
233
234 Static int uhci_device_bulk_init(struct usbd_xfer *);
235 Static void uhci_device_bulk_fini(struct usbd_xfer *);
236 Static usbd_status uhci_device_bulk_transfer(struct usbd_xfer *);
237 Static usbd_status uhci_device_bulk_start(struct usbd_xfer *);
238 Static void uhci_device_bulk_abort(struct usbd_xfer *);
239 Static void uhci_device_bulk_close(struct usbd_pipe *);
240 Static void uhci_device_bulk_done(struct usbd_xfer *);
241
242 Static int uhci_device_isoc_init(struct usbd_xfer *);
243 Static void uhci_device_isoc_fini(struct usbd_xfer *);
244 Static usbd_status uhci_device_isoc_transfer(struct usbd_xfer *);
245 Static void uhci_device_isoc_abort(struct usbd_xfer *);
246 Static void uhci_device_isoc_close(struct usbd_pipe *);
247 Static void uhci_device_isoc_done(struct usbd_xfer *);
248
249 Static usbd_status uhci_root_intr_transfer(struct usbd_xfer *);
250 Static usbd_status uhci_root_intr_start(struct usbd_xfer *);
251 Static void uhci_root_intr_abort(struct usbd_xfer *);
252 Static void uhci_root_intr_close(struct usbd_pipe *);
253 Static void uhci_root_intr_done(struct usbd_xfer *);
254
255 Static usbd_status uhci_open(struct usbd_pipe *);
256 Static void uhci_poll(struct usbd_bus *);
257 Static void uhci_softintr(void *);
258
259 Static void uhci_add_intr(uhci_softc_t *, uhci_soft_qh_t *);
260 Static void uhci_remove_intr(uhci_softc_t *, uhci_soft_qh_t *);
261 Static usbd_status uhci_device_setintr(uhci_softc_t *,
262 struct uhci_pipe *, int);
263
264 Static void uhci_device_clear_toggle(struct usbd_pipe *);
265 Static void uhci_noop(struct usbd_pipe *);
266
267 static inline uhci_soft_qh_t *
268 uhci_find_prev_qh(uhci_soft_qh_t *, uhci_soft_qh_t *);
269
270 #ifdef UHCI_DEBUG
271 Static void uhci_dump_all(uhci_softc_t *);
272 Static void uhci_dumpregs(uhci_softc_t *);
273 Static void uhci_dump_qhs(uhci_soft_qh_t *);
274 Static void uhci_dump_qh(uhci_soft_qh_t *);
275 Static void uhci_dump_tds(uhci_soft_td_t *);
276 Static void uhci_dump_td(uhci_soft_td_t *);
277 Static void uhci_dump_ii(struct uhci_xfer *);
278 void uhci_dump(void);
279 #endif
280
281 #define UBARR(sc) bus_space_barrier((sc)->iot, (sc)->ioh, 0, (sc)->sc_size, \
282 BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE)
283 #define UWRITE1(sc, r, x) \
284 do { UBARR(sc); bus_space_write_1((sc)->iot, (sc)->ioh, (r), (x)); \
285 } while (/*CONSTCOND*/0)
286 #define UWRITE2(sc, r, x) \
287 do { UBARR(sc); bus_space_write_2((sc)->iot, (sc)->ioh, (r), (x)); \
288 } while (/*CONSTCOND*/0)
289 #define UWRITE4(sc, r, x) \
290 do { UBARR(sc); bus_space_write_4((sc)->iot, (sc)->ioh, (r), (x)); \
291 } while (/*CONSTCOND*/0)
292
293 static __inline uint8_t
294 UREAD1(uhci_softc_t *sc, bus_size_t r)
295 {
296
297 UBARR(sc);
298 return bus_space_read_1(sc->iot, sc->ioh, r);
299 }
300
301 static __inline uint16_t
302 UREAD2(uhci_softc_t *sc, bus_size_t r)
303 {
304
305 UBARR(sc);
306 return bus_space_read_2(sc->iot, sc->ioh, r);
307 }
308
309 #ifdef UHCI_DEBUG
310 static __inline uint32_t
311 UREAD4(uhci_softc_t *sc, bus_size_t r)
312 {
313
314 UBARR(sc);
315 return bus_space_read_4(sc->iot, sc->ioh, r);
316 }
317 #endif
318
319 #define UHCICMD(sc, cmd) UWRITE2(sc, UHCI_CMD, cmd)
320 #define UHCISTS(sc) UREAD2(sc, UHCI_STS)
321
322 #define UHCI_RESET_TIMEOUT 100 /* ms, reset timeout */
323
324 #define UHCI_CURFRAME(sc) (UREAD2(sc, UHCI_FRNUM) & UHCI_FRNUM_MASK)
325
326 const struct usbd_bus_methods uhci_bus_methods = {
327 .ubm_open = uhci_open,
328 .ubm_softint = uhci_softintr,
329 .ubm_dopoll = uhci_poll,
330 .ubm_allocx = uhci_allocx,
331 .ubm_freex = uhci_freex,
332 .ubm_abortx = uhci_abortx,
333 .ubm_dying = uhci_dying,
334 .ubm_getlock = uhci_get_lock,
335 .ubm_rhctrl = uhci_roothub_ctrl,
336 };
337
338 const struct usbd_pipe_methods uhci_root_intr_methods = {
339 .upm_transfer = uhci_root_intr_transfer,
340 .upm_start = uhci_root_intr_start,
341 .upm_abort = uhci_root_intr_abort,
342 .upm_close = uhci_root_intr_close,
343 .upm_cleartoggle = uhci_noop,
344 .upm_done = uhci_root_intr_done,
345 };
346
347 const struct usbd_pipe_methods uhci_device_ctrl_methods = {
348 .upm_init = uhci_device_ctrl_init,
349 .upm_fini = uhci_device_ctrl_fini,
350 .upm_transfer = uhci_device_ctrl_transfer,
351 .upm_start = uhci_device_ctrl_start,
352 .upm_abort = uhci_device_ctrl_abort,
353 .upm_close = uhci_device_ctrl_close,
354 .upm_cleartoggle = uhci_noop,
355 .upm_done = uhci_device_ctrl_done,
356 };
357
358 const struct usbd_pipe_methods uhci_device_intr_methods = {
359 .upm_init = uhci_device_intr_init,
360 .upm_fini = uhci_device_intr_fini,
361 .upm_transfer = uhci_device_intr_transfer,
362 .upm_start = uhci_device_intr_start,
363 .upm_abort = uhci_device_intr_abort,
364 .upm_close = uhci_device_intr_close,
365 .upm_cleartoggle = uhci_device_clear_toggle,
366 .upm_done = uhci_device_intr_done,
367 };
368
369 const struct usbd_pipe_methods uhci_device_bulk_methods = {
370 .upm_init = uhci_device_bulk_init,
371 .upm_fini = uhci_device_bulk_fini,
372 .upm_transfer = uhci_device_bulk_transfer,
373 .upm_start = uhci_device_bulk_start,
374 .upm_abort = uhci_device_bulk_abort,
375 .upm_close = uhci_device_bulk_close,
376 .upm_cleartoggle = uhci_device_clear_toggle,
377 .upm_done = uhci_device_bulk_done,
378 };
379
380 const struct usbd_pipe_methods uhci_device_isoc_methods = {
381 .upm_init = uhci_device_isoc_init,
382 .upm_fini = uhci_device_isoc_fini,
383 .upm_transfer = uhci_device_isoc_transfer,
384 .upm_abort = uhci_device_isoc_abort,
385 .upm_close = uhci_device_isoc_close,
386 .upm_cleartoggle = uhci_noop,
387 .upm_done = uhci_device_isoc_done,
388 };
389
390 static inline void
391 uhci_add_intr_list(uhci_softc_t *sc, struct uhci_xfer *ux)
392 {
393
394 TAILQ_INSERT_TAIL(&sc->sc_intrhead, ux, ux_list);
395 }
396
397 static inline void
398 uhci_del_intr_list(uhci_softc_t *sc, struct uhci_xfer *ux)
399 {
400
401 TAILQ_REMOVE(&sc->sc_intrhead, ux, ux_list);
402 }
403
404 static inline uhci_soft_qh_t *
405 uhci_find_prev_qh(uhci_soft_qh_t *pqh, uhci_soft_qh_t *sqh)
406 {
407 UHCIHIST_FUNC(); UHCIHIST_CALLED();
408 DPRINTFN(15, "pqh=%#jx sqh=%#jx", (uintptr_t)pqh, (uintptr_t)sqh, 0, 0);
409
410 for (; pqh->hlink != sqh; pqh = pqh->hlink) {
411 #if defined(DIAGNOSTIC) || defined(UHCI_DEBUG)
412 usb_syncmem(&pqh->dma,
413 pqh->offs + offsetof(uhci_qh_t, qh_hlink),
414 sizeof(pqh->qh.qh_hlink),
415 BUS_DMASYNC_POSTWRITE);
416 if (le32toh(pqh->qh.qh_hlink) & UHCI_PTR_T) {
417 printf("%s: QH not found\n", __func__);
418 return NULL;
419 }
420 #endif
421 }
422 return pqh;
423 }
424
425 void
426 uhci_globalreset(uhci_softc_t *sc)
427 {
428 UHCICMD(sc, UHCI_CMD_GRESET); /* global reset */
429 usb_delay_ms(&sc->sc_bus, USB_BUS_RESET_DELAY); /* wait a little */
430 UHCICMD(sc, 0); /* do nothing */
431 }
432
433 int
434 uhci_init(uhci_softc_t *sc)
435 {
436 usbd_status err;
437 int i, j;
438 uhci_soft_qh_t *clsqh, *chsqh, *bsqh, *sqh, *lsqh;
439 uhci_soft_td_t *std;
440
441 UHCIHIST_FUNC(); UHCIHIST_CALLED();
442
443 #ifdef UHCI_DEBUG
444 thesc = sc;
445
446 if (uhcidebug >= 2)
447 uhci_dumpregs(sc);
448 #endif
449
450 sc->sc_suspend = PWR_RESUME;
451
452 UWRITE2(sc, UHCI_INTR, 0); /* disable interrupts */
453 uhci_globalreset(sc); /* reset the controller */
454 uhci_reset(sc);
455
456 /* Allocate and initialize real frame array. */
457 err = usb_allocmem(&sc->sc_bus,
458 UHCI_FRAMELIST_COUNT * sizeof(uhci_physaddr_t),
459 UHCI_FRAMELIST_ALIGN, &sc->sc_dma);
460 if (err)
461 return err;
462 sc->sc_pframes = KERNADDR(&sc->sc_dma, 0);
463 UWRITE2(sc, UHCI_FRNUM, 0); /* set frame number to 0 */
464 UWRITE4(sc, UHCI_FLBASEADDR, DMAADDR(&sc->sc_dma, 0)); /* set frame list*/
465
466 /* Initialise mutex early for uhci_alloc_* */
467 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB);
468 mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_USB);
469
470 /*
471 * Allocate a TD, inactive, that hangs from the last QH.
472 * This is to avoid a bug in the PIIX that makes it run berserk
473 * otherwise.
474 */
475 std = uhci_alloc_std(sc);
476 if (std == NULL)
477 return ENOMEM;
478 std->link.std = NULL;
479 std->td.td_link = htole32(UHCI_PTR_T);
480 std->td.td_status = htole32(0); /* inactive */
481 std->td.td_token = htole32(0);
482 std->td.td_buffer = htole32(0);
483 usb_syncmem(&std->dma, std->offs, sizeof(std->td),
484 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
485
486 /* Allocate the dummy QH marking the end and used for looping the QHs.*/
487 lsqh = uhci_alloc_sqh(sc);
488 if (lsqh == NULL)
489 goto fail1;
490 lsqh->hlink = NULL;
491 lsqh->qh.qh_hlink = htole32(UHCI_PTR_T); /* end of QH chain */
492 lsqh->elink = std;
493 lsqh->qh.qh_elink = htole32(std->physaddr | UHCI_PTR_TD);
494 sc->sc_last_qh = lsqh;
495 usb_syncmem(&lsqh->dma, lsqh->offs, sizeof(lsqh->qh),
496 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
497
498 /* Allocate the dummy QH where bulk traffic will be queued. */
499 bsqh = uhci_alloc_sqh(sc);
500 if (bsqh == NULL)
501 goto fail2;
502 bsqh->hlink = lsqh;
503 bsqh->qh.qh_hlink = htole32(lsqh->physaddr | UHCI_PTR_QH);
504 bsqh->elink = NULL;
505 bsqh->qh.qh_elink = htole32(UHCI_PTR_T);
506 sc->sc_bulk_start = sc->sc_bulk_end = bsqh;
507 usb_syncmem(&bsqh->dma, bsqh->offs, sizeof(bsqh->qh),
508 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
509
510 /* Allocate dummy QH where high speed control traffic will be queued. */
511 chsqh = uhci_alloc_sqh(sc);
512 if (chsqh == NULL)
513 goto fail3;
514 chsqh->hlink = bsqh;
515 chsqh->qh.qh_hlink = htole32(bsqh->physaddr | UHCI_PTR_QH);
516 chsqh->elink = NULL;
517 chsqh->qh.qh_elink = htole32(UHCI_PTR_T);
518 sc->sc_hctl_start = sc->sc_hctl_end = chsqh;
519 usb_syncmem(&chsqh->dma, chsqh->offs, sizeof(chsqh->qh),
520 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
521
522 /* Allocate dummy QH where control traffic will be queued. */
523 clsqh = uhci_alloc_sqh(sc);
524 if (clsqh == NULL)
525 goto fail4;
526 clsqh->hlink = chsqh;
527 clsqh->qh.qh_hlink = htole32(chsqh->physaddr | UHCI_PTR_QH);
528 clsqh->elink = NULL;
529 clsqh->qh.qh_elink = htole32(UHCI_PTR_T);
530 sc->sc_lctl_start = sc->sc_lctl_end = clsqh;
531 usb_syncmem(&clsqh->dma, clsqh->offs, sizeof(clsqh->qh),
532 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
533
534 /*
535 * Make all (virtual) frame list pointers point to the interrupt
536 * queue heads and the interrupt queue heads at the control
537 * queue head and point the physical frame list to the virtual.
538 */
539 for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) {
540 std = uhci_alloc_std(sc);
541 sqh = uhci_alloc_sqh(sc);
542 if (std == NULL || sqh == NULL)
543 return USBD_NOMEM;
544 std->link.sqh = sqh;
545 std->td.td_link = htole32(sqh->physaddr | UHCI_PTR_QH);
546 std->td.td_status = htole32(UHCI_TD_IOS); /* iso, inactive */
547 std->td.td_token = htole32(0);
548 std->td.td_buffer = htole32(0);
549 usb_syncmem(&std->dma, std->offs, sizeof(std->td),
550 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
551 sqh->hlink = clsqh;
552 sqh->qh.qh_hlink = htole32(clsqh->physaddr | UHCI_PTR_QH);
553 sqh->elink = NULL;
554 sqh->qh.qh_elink = htole32(UHCI_PTR_T);
555 usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh),
556 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
557 sc->sc_vframes[i].htd = std;
558 sc->sc_vframes[i].etd = std;
559 sc->sc_vframes[i].hqh = sqh;
560 sc->sc_vframes[i].eqh = sqh;
561 for (j = i;
562 j < UHCI_FRAMELIST_COUNT;
563 j += UHCI_VFRAMELIST_COUNT)
564 sc->sc_pframes[j] = htole32(std->physaddr);
565 }
566 usb_syncmem(&sc->sc_dma, 0,
567 UHCI_FRAMELIST_COUNT * sizeof(uhci_physaddr_t),
568 BUS_DMASYNC_PREWRITE);
569
570
571 TAILQ_INIT(&sc->sc_intrhead);
572
573 sc->sc_xferpool = pool_cache_init(sizeof(struct uhci_xfer), 0, 0, 0,
574 "uhcixfer", NULL, IPL_USB, NULL, NULL, NULL);
575
576 callout_init(&sc->sc_poll_handle, CALLOUT_MPSAFE);
577
578 /* Set up the bus struct. */
579 sc->sc_bus.ub_methods = &uhci_bus_methods;
580 sc->sc_bus.ub_pipesize = sizeof(struct uhci_pipe);
581 sc->sc_bus.ub_usedma = true;
582
583 UHCICMD(sc, UHCI_CMD_MAXP); /* Assume 64 byte packets at frame end */
584
585 DPRINTF("Enabling...", 0, 0, 0, 0);
586
587 err = uhci_run(sc, 1, 0); /* and here we go... */
588 UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE | UHCI_INTR_RIE |
589 UHCI_INTR_IOCE | UHCI_INTR_SPIE); /* enable interrupts */
590 return err;
591
592 fail4:
593 uhci_free_sqh(sc, chsqh);
594 fail3:
595 uhci_free_sqh(sc, lsqh);
596 fail2:
597 uhci_free_sqh(sc, lsqh);
598 fail1:
599 uhci_free_std(sc, std);
600
601 return ENOMEM;
602 }
603
604 int
605 uhci_activate(device_t self, enum devact act)
606 {
607 struct uhci_softc *sc = device_private(self);
608
609 switch (act) {
610 case DVACT_DEACTIVATE:
611 sc->sc_dying = 1;
612 return 0;
613 default:
614 return EOPNOTSUPP;
615 }
616 }
617
618 void
619 uhci_childdet(device_t self, device_t child)
620 {
621 struct uhci_softc *sc = device_private(self);
622
623 KASSERT(sc->sc_child == child);
624 sc->sc_child = NULL;
625 }
626
627 int
628 uhci_detach(struct uhci_softc *sc, int flags)
629 {
630 int rv = 0;
631
632 if (sc->sc_child != NULL)
633 rv = config_detach(sc->sc_child, flags);
634
635 if (rv != 0)
636 return rv;
637
638 callout_halt(&sc->sc_poll_handle, NULL);
639 callout_destroy(&sc->sc_poll_handle);
640
641 mutex_destroy(&sc->sc_lock);
642 mutex_destroy(&sc->sc_intr_lock);
643
644 pool_cache_destroy(sc->sc_xferpool);
645
646 /* XXX free other data structures XXX */
647
648 return rv;
649 }
650
651 struct usbd_xfer *
652 uhci_allocx(struct usbd_bus *bus, unsigned int nframes)
653 {
654 struct uhci_softc *sc = UHCI_BUS2SC(bus);
655 struct usbd_xfer *xfer;
656
657 xfer = pool_cache_get(sc->sc_xferpool, PR_WAITOK);
658 if (xfer != NULL) {
659 memset(xfer, 0, sizeof(struct uhci_xfer));
660
661 #ifdef DIAGNOSTIC
662 struct uhci_xfer *uxfer = UHCI_XFER2UXFER(xfer);
663 uxfer->ux_isdone = true;
664 xfer->ux_state = XFER_BUSY;
665 #endif
666 }
667 return xfer;
668 }
669
670 void
671 uhci_freex(struct usbd_bus *bus, struct usbd_xfer *xfer)
672 {
673 struct uhci_softc *sc = UHCI_BUS2SC(bus);
674 struct uhci_xfer *uxfer __diagused = UHCI_XFER2UXFER(xfer);
675
676 KASSERTMSG(xfer->ux_state == XFER_BUSY ||
677 xfer->ux_status == USBD_NOT_STARTED,
678 "xfer %p state %d\n", xfer, xfer->ux_state);
679 KASSERTMSG(uxfer->ux_isdone || xfer->ux_status == USBD_NOT_STARTED,
680 "xfer %p not done\n", xfer);
681 #ifdef DIAGNOSTIC
682 xfer->ux_state = XFER_FREE;
683 #endif
684 pool_cache_put(sc->sc_xferpool, xfer);
685 }
686
687 Static bool
688 uhci_dying(struct usbd_bus *bus)
689 {
690 struct uhci_softc *sc = UHCI_BUS2SC(bus);
691
692 return sc->sc_dying;
693 }
694
695 Static void
696 uhci_get_lock(struct usbd_bus *bus, kmutex_t **lock)
697 {
698 struct uhci_softc *sc = UHCI_BUS2SC(bus);
699
700 *lock = &sc->sc_lock;
701 }
702
703
704 /*
705 * Handle suspend/resume.
706 *
707 * We need to switch to polling mode here, because this routine is
708 * called from an interrupt context. This is all right since we
709 * are almost suspended anyway.
710 */
711 bool
712 uhci_resume(device_t dv, const pmf_qual_t *qual)
713 {
714 uhci_softc_t *sc = device_private(dv);
715 int cmd;
716
717 mutex_spin_enter(&sc->sc_intr_lock);
718
719 cmd = UREAD2(sc, UHCI_CMD);
720 sc->sc_bus.ub_usepolling++;
721 UWRITE2(sc, UHCI_INTR, 0);
722 uhci_globalreset(sc);
723 uhci_reset(sc);
724 if (cmd & UHCI_CMD_RS)
725 uhci_run(sc, 0, 1);
726
727 /* restore saved state */
728 UWRITE4(sc, UHCI_FLBASEADDR, DMAADDR(&sc->sc_dma, 0));
729 UWRITE2(sc, UHCI_FRNUM, sc->sc_saved_frnum);
730 UWRITE1(sc, UHCI_SOF, sc->sc_saved_sof);
731
732 UHCICMD(sc, cmd | UHCI_CMD_FGR); /* force resume */
733 usb_delay_ms_locked(&sc->sc_bus, USB_RESUME_DELAY, &sc->sc_intr_lock);
734 UHCICMD(sc, cmd & ~UHCI_CMD_EGSM); /* back to normal */
735 UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE |
736 UHCI_INTR_RIE | UHCI_INTR_IOCE | UHCI_INTR_SPIE);
737 UHCICMD(sc, UHCI_CMD_MAXP);
738 uhci_run(sc, 1, 1); /* and start traffic again */
739 usb_delay_ms_locked(&sc->sc_bus, USB_RESUME_RECOVERY, &sc->sc_intr_lock);
740 sc->sc_bus.ub_usepolling--;
741 if (sc->sc_intr_xfer != NULL)
742 callout_reset(&sc->sc_poll_handle, sc->sc_ival, uhci_poll_hub,
743 sc->sc_intr_xfer);
744 #ifdef UHCI_DEBUG
745 if (uhcidebug >= 2)
746 uhci_dumpregs(sc);
747 #endif
748
749 sc->sc_suspend = PWR_RESUME;
750 mutex_spin_exit(&sc->sc_intr_lock);
751
752 return true;
753 }
754
755 bool
756 uhci_suspend(device_t dv, const pmf_qual_t *qual)
757 {
758 uhci_softc_t *sc = device_private(dv);
759 int cmd;
760
761 mutex_spin_enter(&sc->sc_intr_lock);
762
763 cmd = UREAD2(sc, UHCI_CMD);
764
765 #ifdef UHCI_DEBUG
766 if (uhcidebug >= 2)
767 uhci_dumpregs(sc);
768 #endif
769 if (sc->sc_intr_xfer != NULL)
770 callout_stop(&sc->sc_poll_handle);
771 sc->sc_suspend = PWR_SUSPEND;
772 sc->sc_bus.ub_usepolling++;
773
774 uhci_run(sc, 0, 1); /* stop the controller */
775 cmd &= ~UHCI_CMD_RS;
776
777 /* save some state if BIOS doesn't */
778 sc->sc_saved_frnum = UREAD2(sc, UHCI_FRNUM);
779 sc->sc_saved_sof = UREAD1(sc, UHCI_SOF);
780
781 UWRITE2(sc, UHCI_INTR, 0); /* disable intrs */
782
783 UHCICMD(sc, cmd | UHCI_CMD_EGSM); /* enter suspend */
784 usb_delay_ms_locked(&sc->sc_bus, USB_RESUME_WAIT, &sc->sc_intr_lock);
785 sc->sc_bus.ub_usepolling--;
786
787 mutex_spin_exit(&sc->sc_intr_lock);
788
789 return true;
790 }
791
792 #ifdef UHCI_DEBUG
793 Static void
794 uhci_dumpregs(uhci_softc_t *sc)
795 {
796 UHCIHIST_FUNC(); UHCIHIST_CALLED();
797 DPRINTF("cmd =%04jx sts =%04jx intr =%04jx frnum =%04jx",
798 UREAD2(sc, UHCI_CMD), UREAD2(sc, UHCI_STS),
799 UREAD2(sc, UHCI_INTR), UREAD2(sc, UHCI_FRNUM));
800 DPRINTF("sof =%04jx portsc1=%04jx portsc2=%04jx flbase=%08jx",
801 UREAD1(sc, UHCI_SOF), UREAD2(sc, UHCI_PORTSC1),
802 UREAD2(sc, UHCI_PORTSC2), UREAD4(sc, UHCI_FLBASEADDR));
803 }
804
805 void
806 uhci_dump_td(uhci_soft_td_t *p)
807 {
808 UHCIHIST_FUNC(); UHCIHIST_CALLED();
809
810 usb_syncmem(&p->dma, p->offs, sizeof(p->td),
811 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
812
813 DPRINTF("TD(%#jx) at 0x%08jx", (uintptr_t)p, p->physaddr, 0, 0);
814 DPRINTF(" link=0x%08jx status=0x%08jx "
815 "token=0x%08x buffer=0x%08x",
816 le32toh(p->td.td_link),
817 le32toh(p->td.td_status),
818 le32toh(p->td.td_token),
819 le32toh(p->td.td_buffer));
820
821 DPRINTF("bitstuff=%jd crcto =%jd nak =%jd babble =%jd",
822 !!(le32toh(p->td.td_status) & UHCI_TD_BITSTUFF),
823 !!(le32toh(p->td.td_status) & UHCI_TD_CRCTO),
824 !!(le32toh(p->td.td_status) & UHCI_TD_NAK),
825 !!(le32toh(p->td.td_status) & UHCI_TD_BABBLE));
826 DPRINTF("dbuffer =%jd stalled =%jd active =%jd ioc =%jd",
827 !!(le32toh(p->td.td_status) & UHCI_TD_DBUFFER),
828 !!(le32toh(p->td.td_status) & UHCI_TD_STALLED),
829 !!(le32toh(p->td.td_status) & UHCI_TD_ACTIVE),
830 !!(le32toh(p->td.td_status) & UHCI_TD_IOC));
831 DPRINTF("ios =%jd ls =%jd spd =%jd",
832 !!(le32toh(p->td.td_status) & UHCI_TD_IOS),
833 !!(le32toh(p->td.td_status) & UHCI_TD_LS),
834 !!(le32toh(p->td.td_status) & UHCI_TD_SPD), 0);
835 DPRINTF("errcnt =%d actlen =%d pid=%02x",
836 UHCI_TD_GET_ERRCNT(le32toh(p->td.td_status)),
837 UHCI_TD_GET_ACTLEN(le32toh(p->td.td_status)),
838 UHCI_TD_GET_PID(le32toh(p->td.td_token)), 0);
839 DPRINTF("addr=%jd endpt=%jd D=%jd maxlen=%jd,",
840 UHCI_TD_GET_DEVADDR(le32toh(p->td.td_token)),
841 UHCI_TD_GET_ENDPT(le32toh(p->td.td_token)),
842 UHCI_TD_GET_DT(le32toh(p->td.td_token)),
843 UHCI_TD_GET_MAXLEN(le32toh(p->td.td_token)));
844 }
845
846 void
847 uhci_dump_qh(uhci_soft_qh_t *sqh)
848 {
849 UHCIHIST_FUNC(); UHCIHIST_CALLED();
850
851 usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh),
852 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
853
854 DPRINTF("QH(%#jx) at 0x%08jx: hlink=%08jx elink=%08jx", (uintptr_t)sqh,
855 (int)sqh->physaddr, le32toh(sqh->qh.qh_hlink),
856 le32toh(sqh->qh.qh_elink));
857
858 usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), BUS_DMASYNC_PREREAD);
859 }
860
861
862 #if 1
863 void
864 uhci_dump(void)
865 {
866 uhci_dump_all(thesc);
867 }
868 #endif
869
870 void
871 uhci_dump_all(uhci_softc_t *sc)
872 {
873 uhci_dumpregs(sc);
874 /*printf("framelist[i].link = %08x\n", sc->sc_framelist[0].link);*/
875 uhci_dump_qhs(sc->sc_lctl_start);
876 }
877
878
879 void
880 uhci_dump_qhs(uhci_soft_qh_t *sqh)
881 {
882 UHCIHIST_FUNC(); UHCIHIST_CALLED();
883
884 uhci_dump_qh(sqh);
885
886 /*
887 * uhci_dump_qhs displays all the QHs and TDs from the given QH onwards
888 * Traverses sideways first, then down.
889 *
890 * QH1
891 * QH2
892 * No QH
893 * TD2.1
894 * TD2.2
895 * TD1.1
896 * etc.
897 *
898 * TD2.x being the TDs queued at QH2 and QH1 being referenced from QH1.
899 */
900
901 usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh),
902 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
903 if (sqh->hlink != NULL && !(le32toh(sqh->qh.qh_hlink) & UHCI_PTR_T))
904 uhci_dump_qhs(sqh->hlink);
905 else
906 DPRINTF("No QH", 0, 0, 0, 0);
907 usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), BUS_DMASYNC_PREREAD);
908
909 if (sqh->elink != NULL && !(le32toh(sqh->qh.qh_elink) & UHCI_PTR_T))
910 uhci_dump_tds(sqh->elink);
911 else
912 DPRINTF("No QH", 0, 0, 0, 0);
913 }
914
915 void
916 uhci_dump_tds(uhci_soft_td_t *std)
917 {
918 uhci_soft_td_t *td;
919 int stop;
920
921 for (td = std; td != NULL; td = td->link.std) {
922 uhci_dump_td(td);
923
924 /*
925 * Check whether the link pointer in this TD marks
926 * the link pointer as end of queue. This avoids
927 * printing the free list in case the queue/TD has
928 * already been moved there (seatbelt).
929 */
930 usb_syncmem(&td->dma, td->offs + offsetof(uhci_td_t, td_link),
931 sizeof(td->td.td_link),
932 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
933 stop = (le32toh(td->td.td_link) & UHCI_PTR_T ||
934 le32toh(td->td.td_link) == 0);
935 usb_syncmem(&td->dma, td->offs + offsetof(uhci_td_t, td_link),
936 sizeof(td->td.td_link), BUS_DMASYNC_PREREAD);
937 if (stop)
938 break;
939 }
940 }
941
942 Static void
943 uhci_dump_ii(struct uhci_xfer *ux)
944 {
945 struct usbd_pipe *pipe;
946 usb_endpoint_descriptor_t *ed;
947 struct usbd_device *dev;
948
949 if (ux == NULL) {
950 printf("ux NULL\n");
951 return;
952 }
953 pipe = ux->ux_xfer.ux_pipe;
954 if (pipe == NULL) {
955 printf("ux %p: done=%d pipe=NULL\n", ux, ux->ux_isdone);
956 return;
957 }
958 if (pipe->up_endpoint == NULL) {
959 printf("ux %p: done=%d pipe=%p pipe->up_endpoint=NULL\n",
960 ux, ux->ux_isdone, pipe);
961 return;
962 }
963 if (pipe->up_dev == NULL) {
964 printf("ux %p: done=%d pipe=%p pipe->up_dev=NULL\n",
965 ux, ux->ux_isdone, pipe);
966 return;
967 }
968 ed = pipe->up_endpoint->ue_edesc;
969 dev = pipe->up_dev;
970 printf("ux %p: done=%d dev=%p vid=0x%04x pid=0x%04x addr=%d pipe=%p ep=0x%02x attr=0x%02x\n",
971 ux, ux->ux_isdone, dev,
972 UGETW(dev->ud_ddesc.idVendor),
973 UGETW(dev->ud_ddesc.idProduct),
974 dev->ud_addr, pipe,
975 ed->bEndpointAddress, ed->bmAttributes);
976 }
977
978 void uhci_dump_iis(struct uhci_softc *sc);
979 void
980 uhci_dump_iis(struct uhci_softc *sc)
981 {
982 struct uhci_xfer *ux;
983
984 printf("interrupt list:\n");
985 TAILQ_FOREACH(ux, &sc->sc_intrhead, ux_list)
986 uhci_dump_ii(ux);
987 }
988
989 void iidump(void);
990 void iidump(void) { uhci_dump_iis(thesc); }
991
992 #endif
993
994 /*
995 * This routine is executed periodically and simulates interrupts
996 * from the root controller interrupt pipe for port status change.
997 */
998 void
999 uhci_poll_hub(void *addr)
1000 {
1001 struct usbd_xfer *xfer = addr;
1002 struct usbd_pipe *pipe = xfer->ux_pipe;
1003 uhci_softc_t *sc;
1004 u_char *p;
1005
1006 UHCIHIST_FUNC(); UHCIHIST_CALLED();
1007
1008 if (__predict_false(pipe->up_dev == NULL || pipe->up_dev->ud_bus == NULL))
1009 return; /* device has detached */
1010 sc = UHCI_PIPE2SC(pipe);
1011 callout_reset(&sc->sc_poll_handle, sc->sc_ival, uhci_poll_hub, xfer);
1012
1013 p = xfer->ux_buf;
1014 p[0] = 0;
1015 if (UREAD2(sc, UHCI_PORTSC1) & (UHCI_PORTSC_CSC|UHCI_PORTSC_OCIC))
1016 p[0] |= 1<<1;
1017 if (UREAD2(sc, UHCI_PORTSC2) & (UHCI_PORTSC_CSC|UHCI_PORTSC_OCIC))
1018 p[0] |= 1<<2;
1019 if (p[0] == 0)
1020 /* No change, try again in a while */
1021 return;
1022
1023 xfer->ux_actlen = 1;
1024 xfer->ux_status = USBD_NORMAL_COMPLETION;
1025 mutex_enter(&sc->sc_lock);
1026 usb_transfer_complete(xfer);
1027 mutex_exit(&sc->sc_lock);
1028 }
1029
1030 void
1031 uhci_root_intr_done(struct usbd_xfer *xfer)
1032 {
1033 }
1034
1035 /*
1036 * Let the last QH loop back to the high speed control transfer QH.
1037 * This is what intel calls "bandwidth reclamation" and improves
1038 * USB performance a lot for some devices.
1039 * If we are already looping, just count it.
1040 */
1041 void
1042 uhci_add_loop(uhci_softc_t *sc)
1043 {
1044 UHCIHIST_FUNC(); UHCIHIST_CALLED();
1045
1046 #ifdef UHCI_DEBUG
1047 if (uhcinoloop)
1048 return;
1049 #endif
1050 if (++sc->sc_loops == 1) {
1051 DPRINTFN(5, "add loop", 0, 0, 0, 0);
1052 /* Note, we don't loop back the soft pointer. */
1053 sc->sc_last_qh->qh.qh_hlink =
1054 htole32(sc->sc_hctl_start->physaddr | UHCI_PTR_QH);
1055 usb_syncmem(&sc->sc_last_qh->dma,
1056 sc->sc_last_qh->offs + offsetof(uhci_qh_t, qh_hlink),
1057 sizeof(sc->sc_last_qh->qh.qh_hlink),
1058 BUS_DMASYNC_PREWRITE);
1059 }
1060 }
1061
1062 void
1063 uhci_rem_loop(uhci_softc_t *sc)
1064 {
1065 UHCIHIST_FUNC(); UHCIHIST_CALLED();
1066
1067 #ifdef UHCI_DEBUG
1068 if (uhcinoloop)
1069 return;
1070 #endif
1071 if (--sc->sc_loops == 0) {
1072 DPRINTFN(5, "remove loop", 0, 0, 0, 0);
1073 sc->sc_last_qh->qh.qh_hlink = htole32(UHCI_PTR_T);
1074 usb_syncmem(&sc->sc_last_qh->dma,
1075 sc->sc_last_qh->offs + offsetof(uhci_qh_t, qh_hlink),
1076 sizeof(sc->sc_last_qh->qh.qh_hlink),
1077 BUS_DMASYNC_PREWRITE);
1078 }
1079 }
1080
1081 /* Add high speed control QH, called with lock held. */
1082 void
1083 uhci_add_hs_ctrl(uhci_softc_t *sc, uhci_soft_qh_t *sqh)
1084 {
1085 uhci_soft_qh_t *eqh;
1086
1087 UHCIHIST_FUNC(); UHCIHIST_CALLED();
1088
1089 KASSERT(mutex_owned(&sc->sc_lock));
1090
1091 DPRINTFN(10, "sqh %#jx", (uintptr_t)sqh, 0, 0, 0);
1092 eqh = sc->sc_hctl_end;
1093 usb_syncmem(&eqh->dma, eqh->offs + offsetof(uhci_qh_t, qh_hlink),
1094 sizeof(eqh->qh.qh_hlink),
1095 BUS_DMASYNC_POSTWRITE);
1096 sqh->hlink = eqh->hlink;
1097 sqh->qh.qh_hlink = eqh->qh.qh_hlink;
1098 usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh),
1099 BUS_DMASYNC_PREWRITE);
1100 eqh->hlink = sqh;
1101 eqh->qh.qh_hlink = htole32(sqh->physaddr | UHCI_PTR_QH);
1102 sc->sc_hctl_end = sqh;
1103 usb_syncmem(&eqh->dma, eqh->offs + offsetof(uhci_qh_t, qh_hlink),
1104 sizeof(eqh->qh.qh_hlink), BUS_DMASYNC_PREWRITE);
1105 #ifdef UHCI_CTL_LOOP
1106 uhci_add_loop(sc);
1107 #endif
1108 }
1109
1110 /* Remove high speed control QH, called with lock held. */
1111 void
1112 uhci_remove_hs_ctrl(uhci_softc_t *sc, uhci_soft_qh_t *sqh)
1113 {
1114 uhci_soft_qh_t *pqh;
1115 uint32_t elink;
1116
1117 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
1118
1119 UHCIHIST_FUNC(); UHCIHIST_CALLED();
1120 DPRINTFN(10, "sqh %#jx", (uintptr_t)sqh, 0, 0, 0);
1121 #ifdef UHCI_CTL_LOOP
1122 uhci_rem_loop(sc);
1123 #endif
1124 /*
1125 * The T bit should be set in the elink of the QH so that the HC
1126 * doesn't follow the pointer. This condition may fail if the
1127 * the transferred packet was short so that the QH still points
1128 * at the last used TD.
1129 * In this case we set the T bit and wait a little for the HC
1130 * to stop looking at the TD.
1131 * Note that if the TD chain is large enough, the controller
1132 * may still be looking at the chain at the end of this function.
1133 * uhci_free_std_chain() will make sure the controller stops
1134 * looking at it quickly, but until then we should not change
1135 * sqh->hlink.
1136 */
1137 usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_elink),
1138 sizeof(sqh->qh.qh_elink),
1139 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
1140 elink = le32toh(sqh->qh.qh_elink);
1141 usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_elink),
1142 sizeof(sqh->qh.qh_elink), BUS_DMASYNC_PREREAD);
1143 if (!(elink & UHCI_PTR_T)) {
1144 sqh->qh.qh_elink = htole32(UHCI_PTR_T);
1145 usb_syncmem(&sqh->dma,
1146 sqh->offs + offsetof(uhci_qh_t, qh_elink),
1147 sizeof(sqh->qh.qh_elink),
1148 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
1149 delay(UHCI_QH_REMOVE_DELAY);
1150 }
1151
1152 pqh = uhci_find_prev_qh(sc->sc_hctl_start, sqh);
1153 usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_hlink),
1154 sizeof(sqh->qh.qh_hlink), BUS_DMASYNC_POSTWRITE);
1155 pqh->hlink = sqh->hlink;
1156 pqh->qh.qh_hlink = sqh->qh.qh_hlink;
1157 usb_syncmem(&pqh->dma, pqh->offs + offsetof(uhci_qh_t, qh_hlink),
1158 sizeof(pqh->qh.qh_hlink), BUS_DMASYNC_PREWRITE);
1159 delay(UHCI_QH_REMOVE_DELAY);
1160 if (sc->sc_hctl_end == sqh)
1161 sc->sc_hctl_end = pqh;
1162 }
1163
1164 /* Add low speed control QH, called with lock held. */
1165 void
1166 uhci_add_ls_ctrl(uhci_softc_t *sc, uhci_soft_qh_t *sqh)
1167 {
1168 uhci_soft_qh_t *eqh;
1169
1170 KASSERT(mutex_owned(&sc->sc_lock));
1171
1172 UHCIHIST_FUNC(); UHCIHIST_CALLED();
1173 DPRINTFN(10, "sqh %#jx", (uintptr_t)sqh, 0, 0, 0);
1174
1175 eqh = sc->sc_lctl_end;
1176 usb_syncmem(&eqh->dma, eqh->offs + offsetof(uhci_qh_t, qh_hlink),
1177 sizeof(eqh->qh.qh_hlink), BUS_DMASYNC_POSTWRITE);
1178 sqh->hlink = eqh->hlink;
1179 sqh->qh.qh_hlink = eqh->qh.qh_hlink;
1180 usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh),
1181 BUS_DMASYNC_PREWRITE);
1182 eqh->hlink = sqh;
1183 eqh->qh.qh_hlink = htole32(sqh->physaddr | UHCI_PTR_QH);
1184 usb_syncmem(&eqh->dma, eqh->offs + offsetof(uhci_qh_t, qh_hlink),
1185 sizeof(eqh->qh.qh_hlink), BUS_DMASYNC_PREWRITE);
1186 sc->sc_lctl_end = sqh;
1187 }
1188
1189 /* Remove low speed control QH, called with lock held. */
1190 void
1191 uhci_remove_ls_ctrl(uhci_softc_t *sc, uhci_soft_qh_t *sqh)
1192 {
1193 uhci_soft_qh_t *pqh;
1194 uint32_t elink;
1195
1196 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
1197
1198 UHCIHIST_FUNC(); UHCIHIST_CALLED();
1199 DPRINTFN(10, "sqh %#jx", (uintptr_t)sqh, 0, 0, 0);
1200
1201 /* See comment in uhci_remove_hs_ctrl() */
1202 usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_elink),
1203 sizeof(sqh->qh.qh_elink),
1204 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
1205 elink = le32toh(sqh->qh.qh_elink);
1206 usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_elink),
1207 sizeof(sqh->qh.qh_elink), BUS_DMASYNC_PREREAD);
1208 if (!(elink & UHCI_PTR_T)) {
1209 sqh->qh.qh_elink = htole32(UHCI_PTR_T);
1210 usb_syncmem(&sqh->dma,
1211 sqh->offs + offsetof(uhci_qh_t, qh_elink),
1212 sizeof(sqh->qh.qh_elink),
1213 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
1214 delay(UHCI_QH_REMOVE_DELAY);
1215 }
1216 pqh = uhci_find_prev_qh(sc->sc_lctl_start, sqh);
1217 usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_hlink),
1218 sizeof(sqh->qh.qh_hlink), BUS_DMASYNC_POSTWRITE);
1219 pqh->hlink = sqh->hlink;
1220 pqh->qh.qh_hlink = sqh->qh.qh_hlink;
1221 usb_syncmem(&pqh->dma, pqh->offs + offsetof(uhci_qh_t, qh_hlink),
1222 sizeof(pqh->qh.qh_hlink),
1223 BUS_DMASYNC_PREWRITE);
1224 delay(UHCI_QH_REMOVE_DELAY);
1225 if (sc->sc_lctl_end == sqh)
1226 sc->sc_lctl_end = pqh;
1227 }
1228
1229 /* Add bulk QH, called with lock held. */
1230 void
1231 uhci_add_bulk(uhci_softc_t *sc, uhci_soft_qh_t *sqh)
1232 {
1233 uhci_soft_qh_t *eqh;
1234
1235 KASSERT(mutex_owned(&sc->sc_lock));
1236
1237 UHCIHIST_FUNC(); UHCIHIST_CALLED();
1238 DPRINTFN(10, "sqh %#jx", (uintptr_t)sqh, 0, 0, 0);
1239
1240 eqh = sc->sc_bulk_end;
1241 usb_syncmem(&eqh->dma, eqh->offs + offsetof(uhci_qh_t, qh_hlink),
1242 sizeof(eqh->qh.qh_hlink), BUS_DMASYNC_POSTWRITE);
1243 sqh->hlink = eqh->hlink;
1244 sqh->qh.qh_hlink = eqh->qh.qh_hlink;
1245 usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh),
1246 BUS_DMASYNC_PREWRITE);
1247 eqh->hlink = sqh;
1248 eqh->qh.qh_hlink = htole32(sqh->physaddr | UHCI_PTR_QH);
1249 usb_syncmem(&eqh->dma, eqh->offs + offsetof(uhci_qh_t, qh_hlink),
1250 sizeof(eqh->qh.qh_hlink), BUS_DMASYNC_PREWRITE);
1251 sc->sc_bulk_end = sqh;
1252 uhci_add_loop(sc);
1253 }
1254
1255 /* Remove bulk QH, called with lock held. */
1256 void
1257 uhci_remove_bulk(uhci_softc_t *sc, uhci_soft_qh_t *sqh)
1258 {
1259 uhci_soft_qh_t *pqh;
1260
1261 KASSERT(mutex_owned(&sc->sc_lock));
1262
1263 UHCIHIST_FUNC(); UHCIHIST_CALLED();
1264 DPRINTFN(10, "sqh %#jx", (uintptr_t)sqh, 0, 0, 0);
1265
1266 uhci_rem_loop(sc);
1267 /* See comment in uhci_remove_hs_ctrl() */
1268 usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_elink),
1269 sizeof(sqh->qh.qh_elink),
1270 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
1271 if (!(sqh->qh.qh_elink & htole32(UHCI_PTR_T))) {
1272 sqh->qh.qh_elink = htole32(UHCI_PTR_T);
1273 usb_syncmem(&sqh->dma,
1274 sqh->offs + offsetof(uhci_qh_t, qh_elink),
1275 sizeof(sqh->qh.qh_elink),
1276 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
1277 delay(UHCI_QH_REMOVE_DELAY);
1278 }
1279 pqh = uhci_find_prev_qh(sc->sc_bulk_start, sqh);
1280 usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_hlink),
1281 sizeof(sqh->qh.qh_hlink), BUS_DMASYNC_POSTWRITE);
1282 pqh->hlink = sqh->hlink;
1283 pqh->qh.qh_hlink = sqh->qh.qh_hlink;
1284 usb_syncmem(&pqh->dma, pqh->offs + offsetof(uhci_qh_t, qh_hlink),
1285 sizeof(pqh->qh.qh_hlink), BUS_DMASYNC_PREWRITE);
1286 delay(UHCI_QH_REMOVE_DELAY);
1287 if (sc->sc_bulk_end == sqh)
1288 sc->sc_bulk_end = pqh;
1289 }
1290
1291 Static int uhci_intr1(uhci_softc_t *);
1292
1293 int
1294 uhci_intr(void *arg)
1295 {
1296 uhci_softc_t *sc = arg;
1297 int ret = 0;
1298
1299 UHCIHIST_FUNC(); UHCIHIST_CALLED();
1300
1301 mutex_spin_enter(&sc->sc_intr_lock);
1302
1303 if (sc->sc_dying || !device_has_power(sc->sc_dev))
1304 goto done;
1305
1306 if (sc->sc_bus.ub_usepolling || UREAD2(sc, UHCI_INTR) == 0) {
1307 DPRINTFN(16, "ignored interrupt while polling", 0, 0, 0, 0);
1308 goto done;
1309 }
1310
1311 ret = uhci_intr1(sc);
1312
1313 done:
1314 mutex_spin_exit(&sc->sc_intr_lock);
1315 return ret;
1316 }
1317
1318 int
1319 uhci_intr1(uhci_softc_t *sc)
1320 {
1321 int status;
1322 int ack;
1323
1324 UHCIHIST_FUNC(); UHCIHIST_CALLED();
1325
1326 #ifdef UHCI_DEBUG
1327 if (uhcidebug >= 15) {
1328 DPRINTF("sc %#jx", (uintptr_t)sc, 0, 0, 0);
1329 uhci_dumpregs(sc);
1330 }
1331 #endif
1332
1333 KASSERT(mutex_owned(&sc->sc_intr_lock));
1334
1335 status = UREAD2(sc, UHCI_STS) & UHCI_STS_ALLINTRS;
1336 /* Check if the interrupt was for us. */
1337 if (status == 0)
1338 return 0;
1339
1340 if (sc->sc_suspend != PWR_RESUME) {
1341 #ifdef DIAGNOSTIC
1342 printf("%s: interrupt while not operating ignored\n",
1343 device_xname(sc->sc_dev));
1344 #endif
1345 UWRITE2(sc, UHCI_STS, status); /* acknowledge the ints */
1346 return 0;
1347 }
1348
1349 ack = 0;
1350 if (status & UHCI_STS_USBINT)
1351 ack |= UHCI_STS_USBINT;
1352 if (status & UHCI_STS_USBEI)
1353 ack |= UHCI_STS_USBEI;
1354 if (status & UHCI_STS_RD) {
1355 ack |= UHCI_STS_RD;
1356 #ifdef UHCI_DEBUG
1357 printf("%s: resume detect\n", device_xname(sc->sc_dev));
1358 #endif
1359 }
1360 if (status & UHCI_STS_HSE) {
1361 ack |= UHCI_STS_HSE;
1362 printf("%s: host system error\n", device_xname(sc->sc_dev));
1363 }
1364 if (status & UHCI_STS_HCPE) {
1365 ack |= UHCI_STS_HCPE;
1366 printf("%s: host controller process error\n",
1367 device_xname(sc->sc_dev));
1368 }
1369
1370 /* When HCHalted=1 and Run/Stop=0 , it is normal */
1371 if ((status & UHCI_STS_HCH) && (UREAD2(sc, UHCI_CMD) & UHCI_CMD_RS)) {
1372 /* no acknowledge needed */
1373 if (!sc->sc_dying) {
1374 printf("%s: host controller halted\n",
1375 device_xname(sc->sc_dev));
1376 #ifdef UHCI_DEBUG
1377 uhci_dump_all(sc);
1378 #endif
1379 }
1380 sc->sc_dying = 1;
1381 }
1382
1383 if (!ack)
1384 return 0; /* nothing to acknowledge */
1385 UWRITE2(sc, UHCI_STS, ack); /* acknowledge the ints */
1386
1387 usb_schedsoftintr(&sc->sc_bus);
1388
1389 DPRINTFN(15, "sc %#jx done", (uintptr_t)sc, 0, 0, 0);
1390
1391 return 1;
1392 }
1393
1394 void
1395 uhci_softintr(void *v)
1396 {
1397 struct usbd_bus *bus = v;
1398 uhci_softc_t *sc = UHCI_BUS2SC(bus);
1399 struct uhci_xfer *ux, *nextux;
1400 ux_completeq_t cq;
1401
1402 UHCIHIST_FUNC(); UHCIHIST_CALLED();
1403 DPRINTF("sc %#jx", (uintptr_t)sc, 0, 0, 0);
1404
1405 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
1406
1407 TAILQ_INIT(&cq);
1408 /*
1409 * Interrupts on UHCI really suck. When the host controller
1410 * interrupts because a transfer is completed there is no
1411 * way of knowing which transfer it was. You can scan down
1412 * the TDs and QHs of the previous frame to limit the search,
1413 * but that assumes that the interrupt was not delayed by more
1414 * than 1 ms, which may not always be true (e.g. after debug
1415 * output on a slow console).
1416 * We scan all interrupt descriptors to see if any have
1417 * completed.
1418 */
1419 TAILQ_FOREACH_SAFE(ux, &sc->sc_intrhead, ux_list, nextux) {
1420 uhci_check_intr(sc, ux, &cq);
1421 }
1422
1423 /*
1424 * We abuse ux_list for the interrupt and complete lists and
1425 * interrupt transfers will get re-added here so use
1426 * the _SAFE version of TAILQ_FOREACH.
1427 */
1428 TAILQ_FOREACH_SAFE(ux, &cq, ux_list, nextux) {
1429 DPRINTF("ux %#jx", (uintptr_t)ux, 0, 0, 0);
1430 usb_transfer_complete(&ux->ux_xfer);
1431 }
1432
1433 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
1434 }
1435
1436 /* Check for an interrupt. */
1437 void
1438 uhci_check_intr(uhci_softc_t *sc, struct uhci_xfer *ux, ux_completeq_t *cqp)
1439 {
1440 uhci_soft_td_t *std, *fstd = NULL, *lstd = NULL;
1441 uint32_t status;
1442
1443 UHCIHIST_FUNC(); UHCIHIST_CALLED();
1444 DPRINTFN(15, "ux %#jx", (uintptr_t)ux, 0, 0, 0);
1445
1446 KASSERT(ux != NULL);
1447
1448 struct usbd_xfer *xfer = &ux->ux_xfer;
1449 if (xfer->ux_status == USBD_CANCELLED ||
1450 xfer->ux_status == USBD_TIMEOUT) {
1451 DPRINTF("aborted xfer %#jx", (uintptr_t)xfer, 0, 0, 0);
1452 return;
1453 }
1454
1455 switch (ux->ux_type) {
1456 case UX_CTRL:
1457 fstd = ux->ux_setup;
1458 lstd = ux->ux_stat;
1459 break;
1460 case UX_BULK:
1461 case UX_INTR:
1462 case UX_ISOC:
1463 fstd = ux->ux_stdstart;
1464 lstd = ux->ux_stdend;
1465 break;
1466 default:
1467 KASSERT(false);
1468 break;
1469 }
1470 if (fstd == NULL)
1471 return;
1472
1473 KASSERT(lstd != NULL);
1474
1475 usb_syncmem(&lstd->dma,
1476 lstd->offs + offsetof(uhci_td_t, td_status),
1477 sizeof(lstd->td.td_status),
1478 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
1479 status = le32toh(lstd->td.td_status);
1480 usb_syncmem(&lstd->dma,
1481 lstd->offs + offsetof(uhci_td_t, td_status),
1482 sizeof(lstd->td.td_status),
1483 BUS_DMASYNC_PREREAD);
1484
1485 /* If the last TD is not marked active we can complete */
1486 if (!(status & UHCI_TD_ACTIVE)) {
1487 done:
1488 DPRINTFN(12, "ux=%#jx done", (uintptr_t)ux, 0, 0, 0);
1489 uhci_idone(ux, cqp);
1490 return;
1491 }
1492
1493 /*
1494 * If the last TD is still active we need to check whether there
1495 * is an error somewhere in the middle, or whether there was a
1496 * short packet (SPD and not ACTIVE).
1497 */
1498 DPRINTFN(12, "active ux=%#jx", (uintptr_t)ux, 0, 0, 0);
1499 for (std = fstd; std != lstd; std = std->link.std) {
1500 usb_syncmem(&std->dma,
1501 std->offs + offsetof(uhci_td_t, td_status),
1502 sizeof(std->td.td_status),
1503 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
1504 status = le32toh(std->td.td_status);
1505 usb_syncmem(&std->dma,
1506 std->offs + offsetof(uhci_td_t, td_status),
1507 sizeof(std->td.td_status), BUS_DMASYNC_PREREAD);
1508
1509 /* If there's an active TD the xfer isn't done. */
1510 if (status & UHCI_TD_ACTIVE) {
1511 DPRINTFN(12, "ux=%#jx std=%#jx still active",
1512 (uintptr_t)ux, (uintptr_t)std, 0, 0);
1513 return;
1514 }
1515
1516 /* Any kind of error makes the xfer done. */
1517 if (status & UHCI_TD_STALLED)
1518 goto done;
1519
1520 /*
1521 * If the data phase of a control transfer is short, we need
1522 * to complete the status stage
1523 */
1524
1525 if ((status & UHCI_TD_SPD) && ux->ux_type == UX_CTRL) {
1526 struct uhci_pipe *upipe =
1527 UHCI_PIPE2UPIPE(xfer->ux_pipe);
1528 uhci_soft_qh_t *sqh = upipe->ctrl.sqh;
1529 uhci_soft_td_t *stat = upipe->ctrl.stat;
1530
1531 DPRINTFN(12, "ux=%#jx std=%#jx control status"
1532 "phase needs completion", (uintptr_t)ux,
1533 (uintptr_t)ux->ux_stdstart, 0, 0);
1534
1535 sqh->qh.qh_elink =
1536 htole32(stat->physaddr | UHCI_PTR_TD);
1537 usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh),
1538 BUS_DMASYNC_PREWRITE);
1539 break;
1540 }
1541
1542 /* We want short packets, and it is short: it's done */
1543 usb_syncmem(&std->dma,
1544 std->offs + offsetof(uhci_td_t, td_token),
1545 sizeof(std->td.td_token),
1546 BUS_DMASYNC_POSTWRITE);
1547
1548 if ((status & UHCI_TD_SPD) &&
1549 UHCI_TD_GET_ACTLEN(status) <
1550 UHCI_TD_GET_MAXLEN(le32toh(std->td.td_token))) {
1551 goto done;
1552 }
1553 }
1554 }
1555
1556 /* Called with USB lock held. */
1557 void
1558 uhci_idone(struct uhci_xfer *ux, ux_completeq_t *cqp)
1559 {
1560 UHCIHIST_FUNC(); UHCIHIST_CALLED();
1561 struct usbd_xfer *xfer = &ux->ux_xfer;
1562 uhci_softc_t *sc __diagused = UHCI_XFER2SC(xfer);
1563 struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe);
1564 uhci_soft_td_t *std;
1565 uint32_t status = 0, nstatus;
1566 const bool polling __diagused = sc->sc_bus.ub_usepolling;
1567 int actlen;
1568
1569 KASSERT(polling || mutex_owned(&sc->sc_lock));
1570
1571 DPRINTFN(12, "ux=%#jx", (uintptr_t)ux, 0, 0, 0);
1572
1573 /*
1574 * Try to claim this xfer for completion. If it has already
1575 * completed or aborted, drop it on the floor.
1576 */
1577 if (!usbd_xfer_trycomplete(xfer))
1578 return;
1579
1580 #ifdef DIAGNOSTIC
1581 #ifdef UHCI_DEBUG
1582 if (ux->ux_isdone) {
1583 DPRINTF("--- dump start ---", 0, 0, 0, 0);
1584 uhci_dump_ii(ux);
1585 DPRINTF("--- dump end ---", 0, 0, 0, 0);
1586 }
1587 #endif
1588 KASSERT(!ux->ux_isdone);
1589 KASSERTMSG(!ux->ux_isdone, "xfer %p type %d status %d", xfer,
1590 ux->ux_type, xfer->ux_status);
1591 ux->ux_isdone = true;
1592 #endif
1593
1594 if (xfer->ux_nframes != 0) {
1595 /* Isoc transfer, do things differently. */
1596 uhci_soft_td_t **stds = upipe->isoc.stds;
1597 int i, n, nframes, len;
1598
1599 DPRINTFN(5, "ux=%#jx isoc ready", (uintptr_t)ux, 0, 0, 0);
1600
1601 nframes = xfer->ux_nframes;
1602 actlen = 0;
1603 n = ux->ux_curframe;
1604 for (i = 0; i < nframes; i++) {
1605 std = stds[n];
1606 #ifdef UHCI_DEBUG
1607 if (uhcidebug >= 5) {
1608 DPRINTF("isoc TD %jd", i, 0, 0, 0);
1609 DPRINTF("--- dump start ---", 0, 0, 0, 0);
1610 uhci_dump_td(std);
1611 DPRINTF("--- dump end ---", 0, 0, 0, 0);
1612 }
1613 #endif
1614 if (++n >= UHCI_VFRAMELIST_COUNT)
1615 n = 0;
1616 usb_syncmem(&std->dma,
1617 std->offs + offsetof(uhci_td_t, td_status),
1618 sizeof(std->td.td_status),
1619 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
1620 status = le32toh(std->td.td_status);
1621 len = UHCI_TD_GET_ACTLEN(status);
1622 xfer->ux_frlengths[i] = len;
1623 actlen += len;
1624 }
1625 upipe->isoc.inuse -= nframes;
1626 xfer->ux_actlen = actlen;
1627 xfer->ux_status = USBD_NORMAL_COMPLETION;
1628 goto end;
1629 }
1630
1631 #ifdef UHCI_DEBUG
1632 DPRINTFN(10, "ux=%#jx, xfer=%#jx, pipe=%#jx ready", (uintptr_t)ux,
1633 (uintptr_t)xfer, (uintptr_t)upipe, 0);
1634 if (uhcidebug >= 10) {
1635 DPRINTF("--- dump start ---", 0, 0, 0, 0);
1636 uhci_dump_tds(ux->ux_stdstart);
1637 DPRINTF("--- dump end ---", 0, 0, 0, 0);
1638 }
1639 #endif
1640
1641 /* The transfer is done, compute actual length and status. */
1642 actlen = 0;
1643 for (std = ux->ux_stdstart; std != NULL; std = std->link.std) {
1644 usb_syncmem(&std->dma, std->offs, sizeof(std->td),
1645 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
1646 nstatus = le32toh(std->td.td_status);
1647 if (nstatus & UHCI_TD_ACTIVE)
1648 break;
1649
1650 status = nstatus;
1651 if (UHCI_TD_GET_PID(le32toh(std->td.td_token)) !=
1652 UHCI_TD_PID_SETUP)
1653 actlen += UHCI_TD_GET_ACTLEN(status);
1654 else {
1655 /*
1656 * UHCI will report CRCTO in addition to a STALL or NAK
1657 * for a SETUP transaction. See section 3.2.2, "TD
1658 * CONTROL AND STATUS".
1659 */
1660 if (status & (UHCI_TD_STALLED | UHCI_TD_NAK))
1661 status &= ~UHCI_TD_CRCTO;
1662 }
1663 }
1664 /* If there are left over TDs we need to update the toggle. */
1665 if (std != NULL)
1666 upipe->nexttoggle = UHCI_TD_GET_DT(le32toh(std->td.td_token));
1667
1668 status &= UHCI_TD_ERROR;
1669 DPRINTFN(10, "actlen=%jd, status=0x%jx", actlen, status, 0, 0);
1670 xfer->ux_actlen = actlen;
1671 if (status != 0) {
1672
1673 DPRINTFN((status == UHCI_TD_STALLED) * 10,
1674 "error, addr=%jd, endpt=0x%02jx",
1675 xfer->ux_pipe->up_dev->ud_addr,
1676 xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress,
1677 0, 0);
1678 DPRINTFN((status == UHCI_TD_STALLED) * 10,
1679 "bitstuff=%jd crcto =%jd nak =%jd babble =%jd",
1680 !!(status & UHCI_TD_BITSTUFF),
1681 !!(status & UHCI_TD_CRCTO),
1682 !!(status & UHCI_TD_NAK),
1683 !!(status & UHCI_TD_BABBLE));
1684 DPRINTFN((status == UHCI_TD_STALLED) * 10,
1685 "dbuffer =%jd stalled =%jd active =%jd",
1686 !!(status & UHCI_TD_DBUFFER),
1687 !!(status & UHCI_TD_STALLED),
1688 !!(status & UHCI_TD_ACTIVE),
1689 0);
1690
1691 if (status == UHCI_TD_STALLED)
1692 xfer->ux_status = USBD_STALLED;
1693 else
1694 xfer->ux_status = USBD_IOERROR; /* more info XXX */
1695 } else {
1696 xfer->ux_status = USBD_NORMAL_COMPLETION;
1697 }
1698
1699 end:
1700 uhci_del_intr_list(sc, ux);
1701 if (cqp)
1702 TAILQ_INSERT_TAIL(cqp, ux, ux_list);
1703
1704 KASSERT(polling || mutex_owned(&sc->sc_lock));
1705 DPRINTFN(12, "ux=%#jx done", (uintptr_t)ux, 0, 0, 0);
1706 }
1707
1708 void
1709 uhci_poll(struct usbd_bus *bus)
1710 {
1711 uhci_softc_t *sc = UHCI_BUS2SC(bus);
1712
1713 if (UREAD2(sc, UHCI_STS) & UHCI_STS_USBINT) {
1714 mutex_spin_enter(&sc->sc_intr_lock);
1715 uhci_intr1(sc);
1716 mutex_spin_exit(&sc->sc_intr_lock);
1717 }
1718 }
1719
1720 void
1721 uhci_reset(uhci_softc_t *sc)
1722 {
1723 int n;
1724
1725 UHCICMD(sc, UHCI_CMD_HCRESET);
1726 /* The reset bit goes low when the controller is done. */
1727 for (n = 0; n < UHCI_RESET_TIMEOUT &&
1728 (UREAD2(sc, UHCI_CMD) & UHCI_CMD_HCRESET); n++)
1729 usb_delay_ms(&sc->sc_bus, 1);
1730 if (n >= UHCI_RESET_TIMEOUT)
1731 printf("%s: controller did not reset\n",
1732 device_xname(sc->sc_dev));
1733 }
1734
1735 usbd_status
1736 uhci_run(uhci_softc_t *sc, int run, int locked)
1737 {
1738 int n, running;
1739 uint16_t cmd;
1740
1741 UHCIHIST_FUNC(); UHCIHIST_CALLED();
1742
1743 run = run != 0;
1744 if (!locked)
1745 mutex_spin_enter(&sc->sc_intr_lock);
1746
1747 DPRINTF("setting run=%jd", run, 0, 0, 0);
1748 cmd = UREAD2(sc, UHCI_CMD);
1749 if (run)
1750 cmd |= UHCI_CMD_RS;
1751 else
1752 cmd &= ~UHCI_CMD_RS;
1753 UHCICMD(sc, cmd);
1754 for (n = 0; n < 10; n++) {
1755 running = !(UREAD2(sc, UHCI_STS) & UHCI_STS_HCH);
1756 /* return when we've entered the state we want */
1757 if (run == running) {
1758 if (!locked)
1759 mutex_spin_exit(&sc->sc_intr_lock);
1760 DPRINTF("done cmd=0x%jx sts=0x%jx",
1761 UREAD2(sc, UHCI_CMD), UREAD2(sc, UHCI_STS), 0, 0);
1762 return USBD_NORMAL_COMPLETION;
1763 }
1764 usb_delay_ms_locked(&sc->sc_bus, 1, &sc->sc_intr_lock);
1765 }
1766 if (!locked)
1767 mutex_spin_exit(&sc->sc_intr_lock);
1768 printf("%s: cannot %s\n", device_xname(sc->sc_dev),
1769 run ? "start" : "stop");
1770 return USBD_IOERROR;
1771 }
1772
1773 /*
1774 * Memory management routines.
1775 * uhci_alloc_std allocates TDs
1776 * uhci_alloc_sqh allocates QHs
1777 * These two routines do their own free list management,
1778 * partly for speed, partly because allocating DMAable memory
1779 * has page size granularity so much memory would be wasted if
1780 * only one TD/QH (32 bytes) was placed in each allocated chunk.
1781 */
1782
1783 uhci_soft_td_t *
1784 uhci_alloc_std(uhci_softc_t *sc)
1785 {
1786 uhci_soft_td_t *std;
1787 usbd_status err;
1788 int i, offs;
1789 usb_dma_t dma;
1790
1791 UHCIHIST_FUNC(); UHCIHIST_CALLED();
1792
1793 mutex_enter(&sc->sc_lock);
1794 if (sc->sc_freetds == NULL) {
1795 DPRINTFN(2, "allocating chunk", 0, 0, 0, 0);
1796 mutex_exit(&sc->sc_lock);
1797
1798 err = usb_allocmem(&sc->sc_bus, UHCI_STD_SIZE * UHCI_STD_CHUNK,
1799 UHCI_TD_ALIGN, &dma);
1800 if (err)
1801 return NULL;
1802
1803 mutex_enter(&sc->sc_lock);
1804 for (i = 0; i < UHCI_STD_CHUNK; i++) {
1805 offs = i * UHCI_STD_SIZE;
1806 std = KERNADDR(&dma, offs);
1807 std->physaddr = DMAADDR(&dma, offs);
1808 std->dma = dma;
1809 std->offs = offs;
1810 std->link.std = sc->sc_freetds;
1811 sc->sc_freetds = std;
1812 }
1813 }
1814 std = sc->sc_freetds;
1815 sc->sc_freetds = std->link.std;
1816 mutex_exit(&sc->sc_lock);
1817
1818 memset(&std->td, 0, sizeof(uhci_td_t));
1819
1820 return std;
1821 }
1822
1823 #define TD_IS_FREE 0x12345678
1824
1825 void
1826 uhci_free_std_locked(uhci_softc_t *sc, uhci_soft_td_t *std)
1827 {
1828 KASSERT(mutex_owned(&sc->sc_lock));
1829
1830 #ifdef DIAGNOSTIC
1831 if (le32toh(std->td.td_token) == TD_IS_FREE) {
1832 printf("%s: freeing free TD %p\n", __func__, std);
1833 return;
1834 }
1835 std->td.td_token = htole32(TD_IS_FREE);
1836 #endif
1837
1838 std->link.std = sc->sc_freetds;
1839 sc->sc_freetds = std;
1840 }
1841
1842 void
1843 uhci_free_std(uhci_softc_t *sc, uhci_soft_td_t *std)
1844 {
1845 mutex_enter(&sc->sc_lock);
1846 uhci_free_std_locked(sc, std);
1847 mutex_exit(&sc->sc_lock);
1848 }
1849
1850 uhci_soft_qh_t *
1851 uhci_alloc_sqh(uhci_softc_t *sc)
1852 {
1853 uhci_soft_qh_t *sqh;
1854 usbd_status err;
1855 int i, offs;
1856 usb_dma_t dma;
1857
1858 UHCIHIST_FUNC(); UHCIHIST_CALLED();
1859
1860 mutex_enter(&sc->sc_lock);
1861 if (sc->sc_freeqhs == NULL) {
1862 DPRINTFN(2, "allocating chunk", 0, 0, 0, 0);
1863 mutex_exit(&sc->sc_lock);
1864
1865 err = usb_allocmem(&sc->sc_bus, UHCI_SQH_SIZE * UHCI_SQH_CHUNK,
1866 UHCI_QH_ALIGN, &dma);
1867 if (err)
1868 return NULL;
1869
1870 mutex_enter(&sc->sc_lock);
1871 for (i = 0; i < UHCI_SQH_CHUNK; i++) {
1872 offs = i * UHCI_SQH_SIZE;
1873 sqh = KERNADDR(&dma, offs);
1874 sqh->physaddr = DMAADDR(&dma, offs);
1875 sqh->dma = dma;
1876 sqh->offs = offs;
1877 sqh->hlink = sc->sc_freeqhs;
1878 sc->sc_freeqhs = sqh;
1879 }
1880 }
1881 sqh = sc->sc_freeqhs;
1882 sc->sc_freeqhs = sqh->hlink;
1883 mutex_exit(&sc->sc_lock);
1884
1885 memset(&sqh->qh, 0, sizeof(uhci_qh_t));
1886
1887 return sqh;
1888 }
1889
1890 void
1891 uhci_free_sqh(uhci_softc_t *sc, uhci_soft_qh_t *sqh)
1892 {
1893 KASSERT(mutex_owned(&sc->sc_lock));
1894
1895 sqh->hlink = sc->sc_freeqhs;
1896 sc->sc_freeqhs = sqh;
1897 }
1898
1899 #if 0
1900 void
1901 uhci_free_std_chain(uhci_softc_t *sc, uhci_soft_td_t *std,
1902 uhci_soft_td_t *stdend)
1903 {
1904 uhci_soft_td_t *p;
1905 uint32_t td_link;
1906
1907 /*
1908 * to avoid race condition with the controller which may be looking
1909 * at this chain, we need to first invalidate all links, and
1910 * then wait for the controller to move to another queue
1911 */
1912 for (p = std; p != stdend; p = p->link.std) {
1913 usb_syncmem(&p->dma,
1914 p->offs + offsetof(uhci_td_t, td_link),
1915 sizeof(p->td.td_link),
1916 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
1917 td_link = le32toh(p->td.td_link);
1918 usb_syncmem(&p->dma,
1919 p->offs + offsetof(uhci_td_t, td_link),
1920 sizeof(p->td.td_link),
1921 BUS_DMASYNC_PREREAD);
1922 if ((td_link & UHCI_PTR_T) == 0) {
1923 p->td.td_link = htole32(UHCI_PTR_T);
1924 usb_syncmem(&p->dma,
1925 p->offs + offsetof(uhci_td_t, td_link),
1926 sizeof(p->td.td_link),
1927 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
1928 }
1929 }
1930 delay(UHCI_QH_REMOVE_DELAY);
1931
1932 for (; std != stdend; std = p) {
1933 p = std->link.std;
1934 uhci_free_std(sc, std);
1935 }
1936 }
1937 #endif
1938
1939 int
1940 uhci_alloc_std_chain(uhci_softc_t *sc, struct usbd_xfer *xfer, int len,
1941 int rd, uhci_soft_td_t **sp)
1942 {
1943 struct uhci_xfer *uxfer = UHCI_XFER2UXFER(xfer);
1944 uint16_t flags = xfer->ux_flags;
1945 uhci_soft_td_t *p;
1946
1947 UHCIHIST_FUNC(); UHCIHIST_CALLED();
1948
1949 DPRINTFN(8, "xfer=%#jx pipe=%#jx", (uintptr_t)xfer,
1950 (uintptr_t)xfer->ux_pipe, 0, 0);
1951
1952 ASSERT_SLEEPABLE();
1953 KASSERT(sp);
1954
1955 int maxp = UGETW(xfer->ux_pipe->up_endpoint->ue_edesc->wMaxPacketSize);
1956 if (maxp == 0) {
1957 printf("%s: maxp=0\n", __func__);
1958 return EINVAL;
1959 }
1960 size_t ntd = (len + maxp - 1) / maxp;
1961 if (!rd && (flags & USBD_FORCE_SHORT_XFER)) {
1962 ntd++;
1963 }
1964 DPRINTFN(10, "maxp=%jd ntd=%jd", maxp, ntd, 0, 0);
1965
1966 uxfer->ux_stds = NULL;
1967 uxfer->ux_nstd = ntd;
1968 if (ntd == 0) {
1969 *sp = NULL;
1970 DPRINTF("ntd=0", 0, 0, 0, 0);
1971 return 0;
1972 }
1973 uxfer->ux_stds = kmem_alloc(sizeof(uhci_soft_td_t *) * ntd,
1974 KM_SLEEP);
1975
1976 for (int i = 0; i < ntd; i++) {
1977 p = uhci_alloc_std(sc);
1978 if (p == NULL) {
1979 if (i != 0) {
1980 uxfer->ux_nstd = i;
1981 uhci_free_stds(sc, uxfer);
1982 }
1983 kmem_free(uxfer->ux_stds,
1984 sizeof(uhci_soft_td_t *) * ntd);
1985 return ENOMEM;
1986 }
1987 uxfer->ux_stds[i] = p;
1988 }
1989
1990 *sp = uxfer->ux_stds[0];
1991
1992 return 0;
1993 }
1994
1995 Static void
1996 uhci_free_stds(uhci_softc_t *sc, struct uhci_xfer *ux)
1997 {
1998 UHCIHIST_FUNC(); UHCIHIST_CALLED();
1999
2000 DPRINTFN(8, "ux=%#jx", (uintptr_t)ux, 0, 0, 0);
2001
2002 mutex_enter(&sc->sc_lock);
2003 for (size_t i = 0; i < ux->ux_nstd; i++) {
2004 uhci_soft_td_t *std = ux->ux_stds[i];
2005 #ifdef DIAGNOSTIC
2006 if (le32toh(std->td.td_token) == TD_IS_FREE) {
2007 printf("%s: freeing free TD %p\n", __func__, std);
2008 return;
2009 }
2010 std->td.td_token = htole32(TD_IS_FREE);
2011 #endif
2012 ux->ux_stds[i]->link.std = sc->sc_freetds;
2013 sc->sc_freetds = std;
2014 }
2015 mutex_exit(&sc->sc_lock);
2016 }
2017
2018
2019 Static void
2020 uhci_reset_std_chain(uhci_softc_t *sc, struct usbd_xfer *xfer,
2021 int length, int isread, int *toggle, uhci_soft_td_t **lstd)
2022 {
2023 struct uhci_xfer *uxfer = UHCI_XFER2UXFER(xfer);
2024 struct usbd_pipe *pipe = xfer->ux_pipe;
2025 usb_dma_t *dma = &xfer->ux_dmabuf;
2026 uint16_t flags = xfer->ux_flags;
2027 uhci_soft_td_t *std, *prev;
2028 int len = length;
2029 int tog = *toggle;
2030 int maxp;
2031 uint32_t status;
2032 size_t i;
2033
2034 UHCIHIST_FUNC(); UHCIHIST_CALLED();
2035 DPRINTFN(8, "xfer=%#jx len %jd isread %jd toggle %jd", (uintptr_t)xfer,
2036 len, isread, *toggle);
2037
2038 KASSERT(len != 0 || (!isread && (flags & USBD_FORCE_SHORT_XFER)));
2039
2040 maxp = UGETW(pipe->up_endpoint->ue_edesc->wMaxPacketSize);
2041 KASSERT(maxp != 0);
2042
2043 int addr = xfer->ux_pipe->up_dev->ud_addr;
2044 int endpt = xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress;
2045
2046 status = UHCI_TD_ZERO_ACTLEN(UHCI_TD_SET_ERRCNT(3) | UHCI_TD_ACTIVE);
2047 if (pipe->up_dev->ud_speed == USB_SPEED_LOW)
2048 status |= UHCI_TD_LS;
2049 if (flags & USBD_SHORT_XFER_OK)
2050 status |= UHCI_TD_SPD;
2051 usb_syncmem(dma, 0, len,
2052 isread ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
2053 std = prev = NULL;
2054 for (i = 0; len != 0 && i < uxfer->ux_nstd; i++, prev = std) {
2055 int l = len;
2056 std = uxfer->ux_stds[i];
2057 if (l > maxp)
2058 l = maxp;
2059
2060 if (prev) {
2061 prev->link.std = std;
2062 prev->td.td_link = htole32(
2063 std->physaddr | UHCI_PTR_VF | UHCI_PTR_TD
2064 );
2065 usb_syncmem(&prev->dma, prev->offs, sizeof(prev->td),
2066 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2067 }
2068
2069 usb_syncmem(&std->dma, std->offs, sizeof(std->td),
2070 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
2071
2072 std->td.td_link = htole32(UHCI_PTR_T | UHCI_PTR_VF | UHCI_PTR_TD);
2073 std->td.td_status = htole32(status);
2074 std->td.td_token = htole32(
2075 UHCI_TD_SET_ENDPT(UE_GET_ADDR(endpt)) |
2076 UHCI_TD_SET_DEVADDR(addr) |
2077 UHCI_TD_SET_PID(isread ? UHCI_TD_PID_IN : UHCI_TD_PID_OUT) |
2078 UHCI_TD_SET_DT(tog) |
2079 UHCI_TD_SET_MAXLEN(l)
2080 );
2081 std->td.td_buffer = htole32(DMAADDR(dma, i * maxp));
2082
2083 std->link.std = NULL;
2084
2085 usb_syncmem(&std->dma, std->offs, sizeof(std->td),
2086 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2087 tog ^= 1;
2088
2089 len -= l;
2090 }
2091 KASSERTMSG(len == 0, "xfer %p alen %d len %d mps %d ux_nqtd %zu i %zu",
2092 xfer, length, len, maxp, uxfer->ux_nstd, i);
2093
2094 if (!isread &&
2095 (flags & USBD_FORCE_SHORT_XFER) &&
2096 length % maxp == 0) {
2097 /* Force a 0 length transfer at the end. */
2098 KASSERTMSG(i < uxfer->ux_nstd, "i=%zu nstd=%zu", i,
2099 uxfer->ux_nstd);
2100 std = uxfer->ux_stds[i++];
2101
2102 std->td.td_link = htole32(UHCI_PTR_T | UHCI_PTR_VF | UHCI_PTR_TD);
2103 std->td.td_status = htole32(status);
2104 std->td.td_token = htole32(
2105 UHCI_TD_SET_ENDPT(UE_GET_ADDR(endpt)) |
2106 UHCI_TD_SET_DEVADDR(addr) |
2107 UHCI_TD_SET_PID(UHCI_TD_PID_OUT) |
2108 UHCI_TD_SET_DT(tog) |
2109 UHCI_TD_SET_MAXLEN(0)
2110 );
2111 std->td.td_buffer = 0;
2112 usb_syncmem(&std->dma, std->offs, sizeof(std->td),
2113 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2114
2115 std->link.std = NULL;
2116 if (prev) {
2117 prev->link.std = std;
2118 prev->td.td_link = htole32(
2119 std->physaddr | UHCI_PTR_VF | UHCI_PTR_TD
2120 );
2121 usb_syncmem(&prev->dma, prev->offs, sizeof(prev->td),
2122 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2123 }
2124 tog ^= 1;
2125 }
2126 *lstd = std;
2127 *toggle = tog;
2128 }
2129
2130 void
2131 uhci_device_clear_toggle(struct usbd_pipe *pipe)
2132 {
2133 struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(pipe);
2134 upipe->nexttoggle = 0;
2135 }
2136
2137 void
2138 uhci_noop(struct usbd_pipe *pipe)
2139 {
2140 }
2141
2142 int
2143 uhci_device_bulk_init(struct usbd_xfer *xfer)
2144 {
2145 uhci_softc_t *sc = UHCI_XFER2SC(xfer);
2146 struct uhci_xfer *uxfer = UHCI_XFER2UXFER(xfer);
2147 usb_endpoint_descriptor_t *ed = xfer->ux_pipe->up_endpoint->ue_edesc;
2148 int endpt = ed->bEndpointAddress;
2149 int isread = UE_GET_DIR(endpt) == UE_DIR_IN;
2150 int len = xfer->ux_bufsize;
2151 int err = 0;
2152
2153
2154 UHCIHIST_FUNC(); UHCIHIST_CALLED();
2155 DPRINTFN(3, "xfer=%#jx len=%jd flags=%jd", (uintptr_t)xfer, len,
2156 xfer->ux_flags, 0);
2157
2158 if (sc->sc_dying)
2159 return USBD_IOERROR;
2160
2161 KASSERT(!(xfer->ux_rqflags & URQ_REQUEST));
2162
2163 uxfer->ux_type = UX_BULK;
2164 err = uhci_alloc_std_chain(sc, xfer, len, isread, &uxfer->ux_stdstart);
2165 if (err)
2166 return err;
2167
2168 #ifdef UHCI_DEBUG
2169 if (uhcidebug >= 10) {
2170 DPRINTF("--- dump start ---", 0, 0, 0, 0);
2171 uhci_dump_tds(uxfer->ux_stdstart);
2172 DPRINTF("--- dump end ---", 0, 0, 0, 0);
2173 }
2174 #endif
2175
2176 return 0;
2177 }
2178
2179 Static void
2180 uhci_device_bulk_fini(struct usbd_xfer *xfer)
2181 {
2182 uhci_softc_t *sc = UHCI_XFER2SC(xfer);
2183 struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer);
2184
2185 KASSERT(ux->ux_type == UX_BULK);
2186
2187 if (ux->ux_nstd) {
2188 uhci_free_stds(sc, ux);
2189 kmem_free(ux->ux_stds, sizeof(uhci_soft_td_t *) * ux->ux_nstd);
2190 }
2191 }
2192
2193 usbd_status
2194 uhci_device_bulk_transfer(struct usbd_xfer *xfer)
2195 {
2196 uhci_softc_t *sc = UHCI_XFER2SC(xfer);
2197 usbd_status err;
2198
2199 /* Insert last in queue. */
2200 mutex_enter(&sc->sc_lock);
2201 err = usb_insert_transfer(xfer);
2202 mutex_exit(&sc->sc_lock);
2203 if (err)
2204 return err;
2205
2206 /*
2207 * Pipe isn't running (otherwise err would be USBD_INPROG),
2208 * so start it first.
2209 */
2210 return uhci_device_bulk_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue));
2211 }
2212
2213 usbd_status
2214 uhci_device_bulk_start(struct usbd_xfer *xfer)
2215 {
2216 struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe);
2217 struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer);
2218 uhci_softc_t *sc = UHCI_XFER2SC(xfer);
2219 uhci_soft_td_t *data, *dataend;
2220 uhci_soft_qh_t *sqh;
2221 const bool polling = sc->sc_bus.ub_usepolling;
2222 int len;
2223 int endpt;
2224 int isread;
2225
2226 UHCIHIST_FUNC(); UHCIHIST_CALLED();
2227 DPRINTFN(3, "xfer=%#jx len=%jd flags=%jd", (uintptr_t)xfer,
2228 xfer->ux_length, xfer->ux_flags, 0);
2229
2230 if (sc->sc_dying)
2231 return USBD_IOERROR;
2232
2233 KASSERT(!(xfer->ux_rqflags & URQ_REQUEST));
2234 KASSERT(xfer->ux_length <= xfer->ux_bufsize);
2235
2236 len = xfer->ux_length;
2237 endpt = upipe->pipe.up_endpoint->ue_edesc->bEndpointAddress;
2238 isread = UE_GET_DIR(endpt) == UE_DIR_IN;
2239 sqh = upipe->bulk.sqh;
2240
2241 /* Take lock here to protect nexttoggle */
2242 if (!polling)
2243 mutex_enter(&sc->sc_lock);
2244
2245 uhci_reset_std_chain(sc, xfer, len, isread, &upipe->nexttoggle,
2246 &dataend);
2247
2248 data = ux->ux_stdstart;
2249 ux->ux_stdend = dataend;
2250 dataend->td.td_status |= htole32(UHCI_TD_IOC);
2251 usb_syncmem(&dataend->dma,
2252 dataend->offs + offsetof(uhci_td_t, td_status),
2253 sizeof(dataend->td.td_status),
2254 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2255
2256 #ifdef UHCI_DEBUG
2257 if (uhcidebug >= 10) {
2258 DPRINTF("--- dump start ---", 0, 0, 0, 0);
2259 DPRINTFN(10, "before transfer", 0, 0, 0, 0);
2260 uhci_dump_tds(data);
2261 DPRINTF("--- dump end ---", 0, 0, 0, 0);
2262 }
2263 #endif
2264
2265 KASSERT(ux->ux_isdone);
2266 #ifdef DIAGNOSTIC
2267 ux->ux_isdone = false;
2268 #endif
2269
2270 sqh->elink = data;
2271 sqh->qh.qh_elink = htole32(data->physaddr | UHCI_PTR_TD);
2272 /* uhci_add_bulk() will do usb_syncmem(sqh) */
2273
2274 uhci_add_bulk(sc, sqh);
2275 uhci_add_intr_list(sc, ux);
2276 usbd_xfer_schedule_timeout(xfer);
2277 xfer->ux_status = USBD_IN_PROGRESS;
2278 if (!polling)
2279 mutex_exit(&sc->sc_lock);
2280
2281 return USBD_IN_PROGRESS;
2282 }
2283
2284 /* Abort a device bulk request. */
2285 void
2286 uhci_device_bulk_abort(struct usbd_xfer *xfer)
2287 {
2288 uhci_softc_t *sc __diagused = UHCI_XFER2SC(xfer);
2289
2290 KASSERT(mutex_owned(&sc->sc_lock));
2291
2292 UHCIHIST_FUNC(); UHCIHIST_CALLED();
2293
2294 usbd_xfer_abort(xfer);
2295 }
2296
2297 /*
2298 * To allow the hardware time to notice we simply wait.
2299 */
2300 Static void
2301 uhci_abortx(struct usbd_xfer *xfer)
2302 {
2303 UHCIHIST_FUNC(); UHCIHIST_CALLED();
2304 struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer);
2305 struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe);
2306 uhci_softc_t *sc = UHCI_XFER2SC(xfer);
2307 uhci_soft_td_t *std;
2308
2309 DPRINTFN(1,"xfer=%#jx", (uintptr_t)xfer, 0, 0, 0);
2310
2311 KASSERT(mutex_owned(&sc->sc_lock));
2312 ASSERT_SLEEPABLE();
2313
2314 KASSERTMSG((xfer->ux_status == USBD_CANCELLED ||
2315 xfer->ux_status == USBD_TIMEOUT),
2316 "bad abort status: %d", xfer->ux_status);
2317
2318 /*
2319 * If we're dying, skip the hardware action and just notify the
2320 * software that we're done.
2321 */
2322 if (sc->sc_dying) {
2323 DPRINTFN(4, "xfer %#jx dying %ju", (uintptr_t)xfer,
2324 xfer->ux_status, 0, 0);
2325 goto dying;
2326 }
2327
2328 /*
2329 * HC Step 1: Make interrupt routine and hardware ignore xfer.
2330 */
2331 uhci_del_intr_list(sc, ux);
2332
2333 DPRINTF("stop ux=%#jx", (uintptr_t)ux, 0, 0, 0);
2334 for (std = ux->ux_stdstart; std != NULL; std = std->link.std) {
2335 usb_syncmem(&std->dma,
2336 std->offs + offsetof(uhci_td_t, td_status),
2337 sizeof(std->td.td_status),
2338 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
2339 std->td.td_status &= htole32(~(UHCI_TD_ACTIVE | UHCI_TD_IOC));
2340 usb_syncmem(&std->dma,
2341 std->offs + offsetof(uhci_td_t, td_status),
2342 sizeof(std->td.td_status),
2343 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2344 }
2345
2346 /*
2347 * HC Step 2: Wait until we know hardware has finished any possible
2348 * use of the xfer.
2349 */
2350 /* Hardware finishes in 1ms */
2351 usb_delay_ms_locked(upipe->pipe.up_dev->ud_bus, 2, &sc->sc_lock);
2352
2353 /*
2354 * HC Step 3: Notify completion to waiting xfers.
2355 */
2356 dying:
2357 #ifdef DIAGNOSTIC
2358 ux->ux_isdone = true;
2359 #endif
2360 usb_transfer_complete(xfer);
2361 DPRINTFN(14, "end", 0, 0, 0, 0);
2362
2363 KASSERT(mutex_owned(&sc->sc_lock));
2364 }
2365
2366 /* Close a device bulk pipe. */
2367 void
2368 uhci_device_bulk_close(struct usbd_pipe *pipe)
2369 {
2370 struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(pipe);
2371 uhci_softc_t *sc = UHCI_PIPE2SC(pipe);
2372
2373 KASSERT(mutex_owned(&sc->sc_lock));
2374
2375 uhci_free_sqh(sc, upipe->bulk.sqh);
2376
2377 pipe->up_endpoint->ue_toggle = upipe->nexttoggle;
2378 }
2379
2380 int
2381 uhci_device_ctrl_init(struct usbd_xfer *xfer)
2382 {
2383 struct uhci_xfer *uxfer = UHCI_XFER2UXFER(xfer);
2384 struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe);
2385 usb_device_request_t *req = &xfer->ux_request;
2386 struct usbd_device *dev = upipe->pipe.up_dev;
2387 uhci_softc_t *sc = dev->ud_bus->ub_hcpriv;
2388 uhci_soft_td_t *data = NULL;
2389 int len;
2390 usbd_status err;
2391 int isread;
2392
2393 UHCIHIST_FUNC(); UHCIHIST_CALLED();
2394 DPRINTFN(3, "xfer=%#jx len=%jd, addr=%jd, endpt=%jd",
2395 (uintptr_t)xfer, xfer->ux_bufsize, dev->ud_addr,
2396 upipe->pipe.up_endpoint->ue_edesc->bEndpointAddress);
2397
2398 isread = req->bmRequestType & UT_READ;
2399 len = xfer->ux_bufsize;
2400
2401 uxfer->ux_type = UX_CTRL;
2402 /* Set up data transaction */
2403 if (len != 0) {
2404 err = uhci_alloc_std_chain(sc, xfer, len, isread, &data);
2405 if (err)
2406 return err;
2407 }
2408 /* Set up interrupt info. */
2409 uxfer->ux_setup = upipe->ctrl.setup;
2410 uxfer->ux_stat = upipe->ctrl.stat;
2411 uxfer->ux_data = data;
2412
2413 return 0;
2414 }
2415
2416 Static void
2417 uhci_device_ctrl_fini(struct usbd_xfer *xfer)
2418 {
2419 uhci_softc_t *sc = UHCI_XFER2SC(xfer);
2420 struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer);
2421
2422 KASSERT(ux->ux_type == UX_CTRL);
2423
2424 if (ux->ux_nstd) {
2425 uhci_free_stds(sc, ux);
2426 kmem_free(ux->ux_stds, sizeof(uhci_soft_td_t *) * ux->ux_nstd);
2427 }
2428 }
2429
2430 usbd_status
2431 uhci_device_ctrl_transfer(struct usbd_xfer *xfer)
2432 {
2433 uhci_softc_t *sc = UHCI_XFER2SC(xfer);
2434 usbd_status err;
2435
2436 /* Insert last in queue. */
2437 mutex_enter(&sc->sc_lock);
2438 err = usb_insert_transfer(xfer);
2439 mutex_exit(&sc->sc_lock);
2440 if (err)
2441 return err;
2442
2443 /*
2444 * Pipe isn't running (otherwise err would be USBD_INPROG),
2445 * so start it first.
2446 */
2447 return uhci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue));
2448 }
2449
2450 usbd_status
2451 uhci_device_ctrl_start(struct usbd_xfer *xfer)
2452 {
2453 uhci_softc_t *sc = UHCI_XFER2SC(xfer);
2454 struct uhci_xfer *uxfer = UHCI_XFER2UXFER(xfer);
2455 struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe);
2456 usb_device_request_t *req = &xfer->ux_request;
2457 struct usbd_device *dev = upipe->pipe.up_dev;
2458 int addr = dev->ud_addr;
2459 int endpt = upipe->pipe.up_endpoint->ue_edesc->bEndpointAddress;
2460 uhci_soft_td_t *setup, *stat, *next, *dataend;
2461 uhci_soft_qh_t *sqh;
2462 const bool polling = sc->sc_bus.ub_usepolling;
2463 int len;
2464 int isread;
2465
2466 UHCIHIST_FUNC(); UHCIHIST_CALLED();
2467
2468 if (sc->sc_dying)
2469 return USBD_IOERROR;
2470
2471 KASSERT(xfer->ux_rqflags & URQ_REQUEST);
2472
2473 DPRINTFN(3, "type=0x%02jx, request=0x%02jx, "
2474 "wValue=0x%04jx, wIndex=0x%04jx",
2475 req->bmRequestType, req->bRequest, UGETW(req->wValue),
2476 UGETW(req->wIndex));
2477 DPRINTFN(3, "len=%jd, addr=%jd, endpt=%jd",
2478 UGETW(req->wLength), dev->ud_addr, endpt, 0);
2479
2480 isread = req->bmRequestType & UT_READ;
2481 len = UGETW(req->wLength);
2482
2483 setup = upipe->ctrl.setup;
2484 stat = upipe->ctrl.stat;
2485 sqh = upipe->ctrl.sqh;
2486
2487 memcpy(KERNADDR(&upipe->ctrl.reqdma, 0), req, sizeof(*req));
2488 usb_syncmem(&upipe->ctrl.reqdma, 0, sizeof(*req), BUS_DMASYNC_PREWRITE);
2489
2490 if (!polling)
2491 mutex_enter(&sc->sc_lock);
2492
2493 /* Set up data transaction */
2494 if (len != 0) {
2495 upipe->nexttoggle = 1;
2496 next = uxfer->ux_data;
2497 uhci_reset_std_chain(sc, xfer, len, isread,
2498 &upipe->nexttoggle, &dataend);
2499 dataend->link.std = stat;
2500 dataend->td.td_link = htole32(stat->physaddr | UHCI_PTR_TD);
2501 usb_syncmem(&dataend->dma,
2502 dataend->offs + offsetof(uhci_td_t, td_link),
2503 sizeof(dataend->td.td_link),
2504 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2505 } else {
2506 next = stat;
2507 }
2508
2509 const uint32_t status = UHCI_TD_ZERO_ACTLEN(
2510 UHCI_TD_SET_ERRCNT(3) |
2511 UHCI_TD_ACTIVE |
2512 (dev->ud_speed == USB_SPEED_LOW ? UHCI_TD_LS : 0)
2513 );
2514 setup->link.std = next;
2515 setup->td.td_link = htole32(next->physaddr | UHCI_PTR_TD);
2516 setup->td.td_status = htole32(status);
2517 setup->td.td_token = htole32(UHCI_TD_SETUP(sizeof(*req), endpt, addr));
2518 setup->td.td_buffer = htole32(DMAADDR(&upipe->ctrl.reqdma, 0));
2519
2520 usb_syncmem(&setup->dma, setup->offs, sizeof(setup->td),
2521 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2522
2523 stat->link.std = NULL;
2524 stat->td.td_link = htole32(UHCI_PTR_T);
2525 stat->td.td_status = htole32(status | UHCI_TD_IOC);
2526 stat->td.td_token =
2527 htole32(isread ? UHCI_TD_OUT(0, endpt, addr, 1) :
2528 UHCI_TD_IN (0, endpt, addr, 1));
2529 stat->td.td_buffer = htole32(0);
2530 usb_syncmem(&stat->dma, stat->offs, sizeof(stat->td),
2531 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2532
2533 #ifdef UHCI_DEBUG
2534 if (uhcidebug >= 10) {
2535 DPRINTF("--- dump start ---", 0, 0, 0, 0);
2536 DPRINTF("before transfer", 0, 0, 0, 0);
2537 uhci_dump_tds(setup);
2538 DPRINTF("--- dump end ---", 0, 0, 0, 0);
2539 }
2540 #endif
2541
2542 /* Set up interrupt info. */
2543 uxfer->ux_setup = setup;
2544 uxfer->ux_stat = stat;
2545 KASSERT(uxfer->ux_isdone);
2546 #ifdef DIAGNOSTIC
2547 uxfer->ux_isdone = false;
2548 #endif
2549
2550 sqh->elink = setup;
2551 sqh->qh.qh_elink = htole32(setup->physaddr | UHCI_PTR_TD);
2552 /* uhci_add_?s_ctrl() will do usb_syncmem(sqh) */
2553
2554 if (dev->ud_speed == USB_SPEED_LOW)
2555 uhci_add_ls_ctrl(sc, sqh);
2556 else
2557 uhci_add_hs_ctrl(sc, sqh);
2558 uhci_add_intr_list(sc, uxfer);
2559 #ifdef UHCI_DEBUG
2560 if (uhcidebug >= 12) {
2561 uhci_soft_td_t *std;
2562 uhci_soft_qh_t *xqh;
2563 uhci_soft_qh_t *sxqh;
2564 int maxqh = 0;
2565 uhci_physaddr_t link;
2566 DPRINTFN(12, "--- dump start ---", 0, 0, 0, 0);
2567 DPRINTFN(12, "follow from [0]", 0, 0, 0, 0);
2568 for (std = sc->sc_vframes[0].htd, link = 0;
2569 (link & UHCI_PTR_QH) == 0;
2570 std = std->link.std) {
2571 link = le32toh(std->td.td_link);
2572 uhci_dump_td(std);
2573 }
2574 sxqh = (uhci_soft_qh_t *)std;
2575 uhci_dump_qh(sxqh);
2576 for (xqh = sxqh;
2577 xqh != NULL;
2578 xqh = (maxqh++ == 5 || xqh->hlink == sxqh ||
2579 xqh->hlink == xqh ? NULL : xqh->hlink)) {
2580 uhci_dump_qh(xqh);
2581 }
2582 DPRINTFN(12, "Enqueued QH:", 0, 0, 0, 0);
2583 uhci_dump_qh(sqh);
2584 uhci_dump_tds(sqh->elink);
2585 DPRINTF("--- dump end ---", 0, 0, 0, 0);
2586 }
2587 #endif
2588 usbd_xfer_schedule_timeout(xfer);
2589 xfer->ux_status = USBD_IN_PROGRESS;
2590 if (!polling)
2591 mutex_exit(&sc->sc_lock);
2592
2593 return USBD_IN_PROGRESS;
2594 }
2595
2596 int
2597 uhci_device_intr_init(struct usbd_xfer *xfer)
2598 {
2599 uhci_softc_t *sc = UHCI_XFER2SC(xfer);
2600 struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer);
2601 usb_endpoint_descriptor_t *ed = xfer->ux_pipe->up_endpoint->ue_edesc;
2602 int endpt = ed->bEndpointAddress;
2603 int isread = UE_GET_DIR(endpt) == UE_DIR_IN;
2604 int len = xfer->ux_bufsize;
2605 int err;
2606
2607 UHCIHIST_FUNC(); UHCIHIST_CALLED();
2608
2609 DPRINTFN(3, "xfer=%#jx len=%jd flags=%jd", (uintptr_t)xfer,
2610 xfer->ux_length, xfer->ux_flags, 0);
2611
2612 KASSERT(!(xfer->ux_rqflags & URQ_REQUEST));
2613 KASSERT(len != 0);
2614
2615 ux->ux_type = UX_INTR;
2616 ux->ux_nstd = 0;
2617 err = uhci_alloc_std_chain(sc, xfer, len, isread, &ux->ux_stdstart);
2618
2619 return err;
2620 }
2621
2622 Static void
2623 uhci_device_intr_fini(struct usbd_xfer *xfer)
2624 {
2625 uhci_softc_t *sc = UHCI_XFER2SC(xfer);
2626 struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer);
2627
2628 KASSERT(ux->ux_type == UX_INTR);
2629
2630 if (ux->ux_nstd) {
2631 uhci_free_stds(sc, ux);
2632 kmem_free(ux->ux_stds, sizeof(uhci_soft_td_t *) * ux->ux_nstd);
2633 }
2634 }
2635
2636 usbd_status
2637 uhci_device_intr_transfer(struct usbd_xfer *xfer)
2638 {
2639 uhci_softc_t *sc = UHCI_XFER2SC(xfer);
2640 usbd_status err;
2641
2642 /* Insert last in queue. */
2643 mutex_enter(&sc->sc_lock);
2644 err = usb_insert_transfer(xfer);
2645 mutex_exit(&sc->sc_lock);
2646 if (err)
2647 return err;
2648
2649 /*
2650 * Pipe isn't running (otherwise err would be USBD_INPROG),
2651 * so start it first.
2652 */
2653 return uhci_device_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue));
2654 }
2655
2656 usbd_status
2657 uhci_device_intr_start(struct usbd_xfer *xfer)
2658 {
2659 struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer);
2660 struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe);
2661 uhci_softc_t *sc = UHCI_XFER2SC(xfer);
2662 uhci_soft_td_t *data, *dataend;
2663 uhci_soft_qh_t *sqh;
2664 const bool polling = sc->sc_bus.ub_usepolling;
2665 int isread, endpt;
2666 int i;
2667
2668 if (sc->sc_dying)
2669 return USBD_IOERROR;
2670
2671 UHCIHIST_FUNC(); UHCIHIST_CALLED();
2672
2673 DPRINTFN(3, "xfer=%#jx len=%jd flags=%jd", (uintptr_t)xfer,
2674 xfer->ux_length, xfer->ux_flags, 0);
2675
2676 KASSERT(!(xfer->ux_rqflags & URQ_REQUEST));
2677 KASSERT(xfer->ux_length <= xfer->ux_bufsize);
2678
2679 endpt = upipe->pipe.up_endpoint->ue_edesc->bEndpointAddress;
2680 isread = UE_GET_DIR(endpt) == UE_DIR_IN;
2681
2682 data = ux->ux_stdstart;
2683
2684 KASSERT(ux->ux_isdone);
2685 #ifdef DIAGNOSTIC
2686 ux->ux_isdone = false;
2687 #endif
2688
2689 /* Take lock to protect nexttoggle */
2690 if (!polling)
2691 mutex_enter(&sc->sc_lock);
2692 uhci_reset_std_chain(sc, xfer, xfer->ux_length, isread,
2693 &upipe->nexttoggle, &dataend);
2694
2695 dataend->td.td_status |= htole32(UHCI_TD_IOC);
2696 usb_syncmem(&dataend->dma,
2697 dataend->offs + offsetof(uhci_td_t, td_status),
2698 sizeof(dataend->td.td_status),
2699 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2700 ux->ux_stdend = dataend;
2701
2702 #ifdef UHCI_DEBUG
2703 if (uhcidebug >= 10) {
2704 DPRINTF("--- dump start ---", 0, 0, 0, 0);
2705 uhci_dump_tds(data);
2706 uhci_dump_qh(upipe->intr.qhs[0]);
2707 DPRINTF("--- dump end ---", 0, 0, 0, 0);
2708 }
2709 #endif
2710
2711 DPRINTFN(10, "qhs[0]=%#jx", (uintptr_t)upipe->intr.qhs[0], 0, 0, 0);
2712 for (i = 0; i < upipe->intr.npoll; i++) {
2713 sqh = upipe->intr.qhs[i];
2714 sqh->elink = data;
2715 sqh->qh.qh_elink = htole32(data->physaddr | UHCI_PTR_TD);
2716 usb_syncmem(&sqh->dma,
2717 sqh->offs + offsetof(uhci_qh_t, qh_elink),
2718 sizeof(sqh->qh.qh_elink),
2719 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2720 }
2721 uhci_add_intr_list(sc, ux);
2722 xfer->ux_status = USBD_IN_PROGRESS;
2723 if (!polling)
2724 mutex_exit(&sc->sc_lock);
2725
2726 #ifdef UHCI_DEBUG
2727 if (uhcidebug >= 10) {
2728 DPRINTF("--- dump start ---", 0, 0, 0, 0);
2729 uhci_dump_tds(data);
2730 uhci_dump_qh(upipe->intr.qhs[0]);
2731 DPRINTF("--- dump end ---", 0, 0, 0, 0);
2732 }
2733 #endif
2734
2735 return USBD_IN_PROGRESS;
2736 }
2737
2738 /* Abort a device control request. */
2739 void
2740 uhci_device_ctrl_abort(struct usbd_xfer *xfer)
2741 {
2742 uhci_softc_t *sc __diagused = UHCI_XFER2SC(xfer);
2743
2744 KASSERT(mutex_owned(&sc->sc_lock));
2745
2746 UHCIHIST_FUNC(); UHCIHIST_CALLED();
2747 usbd_xfer_abort(xfer);
2748 }
2749
2750 /* Close a device control pipe. */
2751 void
2752 uhci_device_ctrl_close(struct usbd_pipe *pipe)
2753 {
2754 uhci_softc_t *sc = UHCI_PIPE2SC(pipe);
2755 struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(pipe);
2756
2757 uhci_free_sqh(sc, upipe->ctrl.sqh);
2758 uhci_free_std_locked(sc, upipe->ctrl.setup);
2759 uhci_free_std_locked(sc, upipe->ctrl.stat);
2760
2761 }
2762
2763 /* Abort a device interrupt request. */
2764 void
2765 uhci_device_intr_abort(struct usbd_xfer *xfer)
2766 {
2767 uhci_softc_t *sc __diagused = UHCI_XFER2SC(xfer);
2768
2769 KASSERT(mutex_owned(&sc->sc_lock));
2770 KASSERT(xfer->ux_pipe->up_intrxfer == xfer);
2771
2772 UHCIHIST_FUNC(); UHCIHIST_CALLED();
2773 DPRINTF("xfer=%#jx", (uintptr_t)xfer, 0, 0, 0);
2774
2775 usbd_xfer_abort(xfer);
2776 }
2777
2778 /* Close a device interrupt pipe. */
2779 void
2780 uhci_device_intr_close(struct usbd_pipe *pipe)
2781 {
2782 struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(pipe);
2783 uhci_softc_t *sc = UHCI_PIPE2SC(pipe);
2784 int i, npoll;
2785
2786 KASSERT(mutex_owned(&sc->sc_lock));
2787
2788 /* Unlink descriptors from controller data structures. */
2789 npoll = upipe->intr.npoll;
2790 for (i = 0; i < npoll; i++)
2791 uhci_remove_intr(sc, upipe->intr.qhs[i]);
2792
2793 /*
2794 * We now have to wait for any activity on the physical
2795 * descriptors to stop.
2796 */
2797 usb_delay_ms_locked(&sc->sc_bus, 2, &sc->sc_lock);
2798
2799 for (i = 0; i < npoll; i++)
2800 uhci_free_sqh(sc, upipe->intr.qhs[i]);
2801 kmem_free(upipe->intr.qhs, npoll * sizeof(uhci_soft_qh_t *));
2802 }
2803
2804 int
2805 uhci_device_isoc_init(struct usbd_xfer *xfer)
2806 {
2807 struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer);
2808
2809 KASSERT(!(xfer->ux_rqflags & URQ_REQUEST));
2810 KASSERT(xfer->ux_nframes != 0);
2811 KASSERT(ux->ux_isdone);
2812
2813 ux->ux_type = UX_ISOC;
2814 return 0;
2815 }
2816
2817 Static void
2818 uhci_device_isoc_fini(struct usbd_xfer *xfer)
2819 {
2820 struct uhci_xfer *ux __diagused = UHCI_XFER2UXFER(xfer);
2821
2822 KASSERT(ux->ux_type == UX_ISOC);
2823 }
2824
2825 usbd_status
2826 uhci_device_isoc_transfer(struct usbd_xfer *xfer)
2827 {
2828 uhci_softc_t *sc = UHCI_XFER2SC(xfer);
2829 usbd_status err __diagused;
2830
2831 UHCIHIST_FUNC(); UHCIHIST_CALLED();
2832 DPRINTFN(5, "xfer=%#jx", (uintptr_t)xfer, 0, 0, 0);
2833
2834 /* Put it on our queue, */
2835 mutex_enter(&sc->sc_lock);
2836 err = usb_insert_transfer(xfer);
2837 mutex_exit(&sc->sc_lock);
2838
2839 KASSERT(err == USBD_NORMAL_COMPLETION);
2840
2841 /* insert into schedule, */
2842
2843 struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe);
2844 struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer);
2845 struct isoc *isoc = &upipe->isoc;
2846 uhci_soft_td_t *std = NULL;
2847 uint32_t buf, len, status, offs;
2848 int i, next, nframes;
2849 int rd = UE_GET_DIR(upipe->pipe.up_endpoint->ue_edesc->bEndpointAddress) == UE_DIR_IN;
2850
2851 DPRINTFN(5, "used=%jd next=%jd xfer=%#jx nframes=%jd",
2852 isoc->inuse, isoc->next, (uintptr_t)xfer, xfer->ux_nframes);
2853
2854 if (sc->sc_dying)
2855 return USBD_IOERROR;
2856
2857 if (xfer->ux_status == USBD_IN_PROGRESS) {
2858 /* This request has already been entered into the frame list */
2859 printf("%s: xfer=%p in frame list\n", __func__, xfer);
2860 /* XXX */
2861 }
2862
2863 #ifdef DIAGNOSTIC
2864 if (isoc->inuse >= UHCI_VFRAMELIST_COUNT)
2865 printf("%s: overflow!\n", __func__);
2866 #endif
2867
2868 KASSERT(xfer->ux_nframes != 0);
2869
2870 mutex_enter(&sc->sc_lock);
2871 next = isoc->next;
2872 if (next == -1) {
2873 /* Not in use yet, schedule it a few frames ahead. */
2874 next = (UREAD2(sc, UHCI_FRNUM) + 3) % UHCI_VFRAMELIST_COUNT;
2875 DPRINTFN(2, "start next=%jd", next, 0, 0, 0);
2876 }
2877
2878 xfer->ux_status = USBD_IN_PROGRESS;
2879 ux->ux_curframe = next;
2880
2881 buf = DMAADDR(&xfer->ux_dmabuf, 0);
2882 offs = 0;
2883 status = UHCI_TD_ZERO_ACTLEN(UHCI_TD_SET_ERRCNT(0) |
2884 UHCI_TD_ACTIVE |
2885 UHCI_TD_IOS);
2886 nframes = xfer->ux_nframes;
2887 for (i = 0; i < nframes; i++) {
2888 std = isoc->stds[next];
2889 if (++next >= UHCI_VFRAMELIST_COUNT)
2890 next = 0;
2891 len = xfer->ux_frlengths[i];
2892 std->td.td_buffer = htole32(buf);
2893 usb_syncmem(&xfer->ux_dmabuf, offs, len,
2894 rd ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
2895 if (i == nframes - 1)
2896 status |= UHCI_TD_IOC;
2897 std->td.td_status = htole32(status);
2898 std->td.td_token &= htole32(~UHCI_TD_MAXLEN_MASK);
2899 std->td.td_token |= htole32(UHCI_TD_SET_MAXLEN(len));
2900 usb_syncmem(&std->dma, std->offs, sizeof(std->td),
2901 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2902 #ifdef UHCI_DEBUG
2903 if (uhcidebug >= 5) {
2904 DPRINTF("--- dump start ---", 0, 0, 0, 0);
2905 DPRINTF("TD %jd", i, 0, 0, 0);
2906 uhci_dump_td(std);
2907 DPRINTF("--- dump end ---", 0, 0, 0, 0);
2908 }
2909 #endif
2910 buf += len;
2911 offs += len;
2912 }
2913 isoc->next = next;
2914 isoc->inuse += xfer->ux_nframes;
2915
2916 /* Set up interrupt info. */
2917 ux->ux_stdstart = std;
2918 ux->ux_stdend = std;
2919
2920 KASSERT(ux->ux_isdone);
2921 #ifdef DIAGNOSTIC
2922 ux->ux_isdone = false;
2923 #endif
2924 uhci_add_intr_list(sc, ux);
2925
2926 mutex_exit(&sc->sc_lock);
2927
2928 return USBD_IN_PROGRESS;
2929 }
2930
2931 void
2932 uhci_device_isoc_abort(struct usbd_xfer *xfer)
2933 {
2934 uhci_softc_t *sc = UHCI_XFER2SC(xfer);
2935 struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe);
2936 struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer);
2937 uhci_soft_td_t **stds = upipe->isoc.stds;
2938 uhci_soft_td_t *std;
2939 int i, n, nframes, maxlen, len;
2940
2941 KASSERT(mutex_owned(&sc->sc_lock));
2942
2943 /* Transfer is already done. */
2944 if (xfer->ux_status != USBD_NOT_STARTED &&
2945 xfer->ux_status != USBD_IN_PROGRESS) {
2946 return;
2947 }
2948
2949 /* Give xfer the requested abort code. */
2950 xfer->ux_status = USBD_CANCELLED;
2951
2952 /* make hardware ignore it, */
2953 nframes = xfer->ux_nframes;
2954 n = ux->ux_curframe;
2955 maxlen = 0;
2956 for (i = 0; i < nframes; i++) {
2957 std = stds[n];
2958 usb_syncmem(&std->dma,
2959 std->offs + offsetof(uhci_td_t, td_status),
2960 sizeof(std->td.td_status),
2961 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
2962 std->td.td_status &= htole32(~(UHCI_TD_ACTIVE | UHCI_TD_IOC));
2963 usb_syncmem(&std->dma,
2964 std->offs + offsetof(uhci_td_t, td_status),
2965 sizeof(std->td.td_status),
2966 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2967 usb_syncmem(&std->dma,
2968 std->offs + offsetof(uhci_td_t, td_token),
2969 sizeof(std->td.td_token),
2970 BUS_DMASYNC_POSTWRITE);
2971 len = UHCI_TD_GET_MAXLEN(le32toh(std->td.td_token));
2972 if (len > maxlen)
2973 maxlen = len;
2974 if (++n >= UHCI_VFRAMELIST_COUNT)
2975 n = 0;
2976 }
2977
2978 /* and wait until we are sure the hardware has finished. */
2979 delay(maxlen);
2980
2981 #ifdef DIAGNOSTIC
2982 ux->ux_isdone = true;
2983 #endif
2984 /* Remove from interrupt list. */
2985 uhci_del_intr_list(sc, ux);
2986
2987 /* Run callback. */
2988 usb_transfer_complete(xfer);
2989
2990 KASSERT(mutex_owned(&sc->sc_lock));
2991 }
2992
2993 void
2994 uhci_device_isoc_close(struct usbd_pipe *pipe)
2995 {
2996 struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(pipe);
2997 uhci_softc_t *sc = UHCI_PIPE2SC(pipe);
2998 uhci_soft_td_t *std, *vstd;
2999 struct isoc *isoc;
3000 int i;
3001
3002 KASSERT(mutex_owned(&sc->sc_lock));
3003
3004 /*
3005 * Make sure all TDs are marked as inactive.
3006 * Wait for completion.
3007 * Unschedule.
3008 * Deallocate.
3009 */
3010 isoc = &upipe->isoc;
3011
3012 for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) {
3013 std = isoc->stds[i];
3014 usb_syncmem(&std->dma,
3015 std->offs + offsetof(uhci_td_t, td_status),
3016 sizeof(std->td.td_status),
3017 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
3018 std->td.td_status &= htole32(~UHCI_TD_ACTIVE);
3019 usb_syncmem(&std->dma,
3020 std->offs + offsetof(uhci_td_t, td_status),
3021 sizeof(std->td.td_status),
3022 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
3023 }
3024 /* wait for completion */
3025 usb_delay_ms_locked(&sc->sc_bus, 2, &sc->sc_lock);
3026
3027 for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) {
3028 std = isoc->stds[i];
3029 for (vstd = sc->sc_vframes[i].htd;
3030 vstd != NULL && vstd->link.std != std;
3031 vstd = vstd->link.std)
3032 ;
3033 if (vstd == NULL) {
3034 /*panic*/
3035 printf("%s: %p not found\n", __func__, std);
3036 mutex_exit(&sc->sc_lock);
3037 return;
3038 }
3039 vstd->link = std->link;
3040 usb_syncmem(&std->dma,
3041 std->offs + offsetof(uhci_td_t, td_link),
3042 sizeof(std->td.td_link),
3043 BUS_DMASYNC_POSTWRITE);
3044 vstd->td.td_link = std->td.td_link;
3045 usb_syncmem(&vstd->dma,
3046 vstd->offs + offsetof(uhci_td_t, td_link),
3047 sizeof(vstd->td.td_link),
3048 BUS_DMASYNC_PREWRITE);
3049 uhci_free_std_locked(sc, std);
3050 }
3051
3052 kmem_free(isoc->stds, UHCI_VFRAMELIST_COUNT * sizeof(uhci_soft_td_t *));
3053 }
3054
3055 usbd_status
3056 uhci_setup_isoc(struct usbd_pipe *pipe)
3057 {
3058 struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(pipe);
3059 uhci_softc_t *sc = UHCI_PIPE2SC(pipe);
3060 int addr = upipe->pipe.up_dev->ud_addr;
3061 int endpt = upipe->pipe.up_endpoint->ue_edesc->bEndpointAddress;
3062 int rd = UE_GET_DIR(endpt) == UE_DIR_IN;
3063 uhci_soft_td_t *std, *vstd;
3064 uint32_t token;
3065 struct isoc *isoc;
3066 int i;
3067
3068 isoc = &upipe->isoc;
3069
3070 isoc->stds = kmem_alloc(
3071 UHCI_VFRAMELIST_COUNT * sizeof(uhci_soft_td_t *), KM_SLEEP);
3072 if (isoc->stds == NULL)
3073 return USBD_NOMEM;
3074
3075 token = rd ? UHCI_TD_IN (0, endpt, addr, 0) :
3076 UHCI_TD_OUT(0, endpt, addr, 0);
3077
3078 /* Allocate the TDs and mark as inactive; */
3079 for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) {
3080 std = uhci_alloc_std(sc);
3081 if (std == 0)
3082 goto bad;
3083 std->td.td_status = htole32(UHCI_TD_IOS); /* iso, inactive */
3084 std->td.td_token = htole32(token);
3085 usb_syncmem(&std->dma, std->offs, sizeof(std->td),
3086 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
3087 isoc->stds[i] = std;
3088 }
3089
3090 mutex_enter(&sc->sc_lock);
3091
3092 /* Insert TDs into schedule. */
3093 for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) {
3094 std = isoc->stds[i];
3095 vstd = sc->sc_vframes[i].htd;
3096 usb_syncmem(&vstd->dma,
3097 vstd->offs + offsetof(uhci_td_t, td_link),
3098 sizeof(vstd->td.td_link),
3099 BUS_DMASYNC_POSTWRITE);
3100 std->link = vstd->link;
3101 std->td.td_link = vstd->td.td_link;
3102 usb_syncmem(&std->dma,
3103 std->offs + offsetof(uhci_td_t, td_link),
3104 sizeof(std->td.td_link),
3105 BUS_DMASYNC_PREWRITE);
3106 vstd->link.std = std;
3107 vstd->td.td_link = htole32(std->physaddr | UHCI_PTR_TD);
3108 usb_syncmem(&vstd->dma,
3109 vstd->offs + offsetof(uhci_td_t, td_link),
3110 sizeof(vstd->td.td_link),
3111 BUS_DMASYNC_PREWRITE);
3112 }
3113 mutex_exit(&sc->sc_lock);
3114
3115 isoc->next = -1;
3116 isoc->inuse = 0;
3117
3118 return USBD_NORMAL_COMPLETION;
3119
3120 bad:
3121 while (--i >= 0)
3122 uhci_free_std(sc, isoc->stds[i]);
3123 kmem_free(isoc->stds, UHCI_VFRAMELIST_COUNT * sizeof(uhci_soft_td_t *));
3124 return USBD_NOMEM;
3125 }
3126
3127 void
3128 uhci_device_isoc_done(struct usbd_xfer *xfer)
3129 {
3130 struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe);
3131 struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer);
3132 int i, offs;
3133 int rd = UE_GET_DIR(upipe->pipe.up_endpoint->ue_edesc->bEndpointAddress) == UE_DIR_IN;
3134
3135 UHCIHIST_FUNC(); UHCIHIST_CALLED();
3136 DPRINTFN(4, "length=%jd, ux_state=0x%08jx",
3137 xfer->ux_actlen, xfer->ux_state, 0, 0);
3138
3139 #ifdef DIAGNOSTIC
3140 if (ux->ux_stdend == NULL) {
3141 printf("%s: xfer=%p stdend==NULL\n", __func__, xfer);
3142 #ifdef UHCI_DEBUG
3143 DPRINTF("--- dump start ---", 0, 0, 0, 0);
3144 uhci_dump_ii(ux);
3145 DPRINTF("--- dump end ---", 0, 0, 0, 0);
3146 #endif
3147 return;
3148 }
3149 #endif
3150
3151 /* Turn off the interrupt since it is active even if the TD is not. */
3152 usb_syncmem(&ux->ux_stdend->dma,
3153 ux->ux_stdend->offs + offsetof(uhci_td_t, td_status),
3154 sizeof(ux->ux_stdend->td.td_status),
3155 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
3156 ux->ux_stdend->td.td_status &= htole32(~UHCI_TD_IOC);
3157 usb_syncmem(&ux->ux_stdend->dma,
3158 ux->ux_stdend->offs + offsetof(uhci_td_t, td_status),
3159 sizeof(ux->ux_stdend->td.td_status),
3160 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
3161
3162 offs = 0;
3163 for (i = 0; i < xfer->ux_nframes; i++) {
3164 usb_syncmem(&xfer->ux_dmabuf, offs, xfer->ux_frlengths[i],
3165 rd ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
3166 offs += xfer->ux_frlengths[i];
3167 }
3168 }
3169
3170 void
3171 uhci_device_intr_done(struct usbd_xfer *xfer)
3172 {
3173 uhci_softc_t *sc __diagused = UHCI_XFER2SC(xfer);
3174 struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe);
3175 uhci_soft_qh_t *sqh;
3176 int i, npoll;
3177
3178 UHCIHIST_FUNC(); UHCIHIST_CALLED();
3179 DPRINTFN(5, "length=%jd", xfer->ux_actlen, 0, 0, 0);
3180
3181 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
3182
3183 npoll = upipe->intr.npoll;
3184 for (i = 0; i < npoll; i++) {
3185 sqh = upipe->intr.qhs[i];
3186 sqh->elink = NULL;
3187 sqh->qh.qh_elink = htole32(UHCI_PTR_T);
3188 usb_syncmem(&sqh->dma,
3189 sqh->offs + offsetof(uhci_qh_t, qh_elink),
3190 sizeof(sqh->qh.qh_elink),
3191 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
3192 }
3193 const int endpt = upipe->pipe.up_endpoint->ue_edesc->bEndpointAddress;
3194 const bool isread = UE_GET_DIR(endpt) == UE_DIR_IN;
3195 usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length,
3196 isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
3197 }
3198
3199 /* Deallocate request data structures */
3200 void
3201 uhci_device_ctrl_done(struct usbd_xfer *xfer)
3202 {
3203 uhci_softc_t *sc = UHCI_XFER2SC(xfer);
3204 struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe);
3205 int len = UGETW(xfer->ux_request.wLength);
3206 int isread = (xfer->ux_request.bmRequestType & UT_READ);
3207
3208 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
3209
3210 UHCIHIST_FUNC(); UHCIHIST_CALLED();
3211
3212 KASSERT(xfer->ux_rqflags & URQ_REQUEST);
3213
3214 /* XXXNH move to uhci_idone??? */
3215 if (upipe->pipe.up_dev->ud_speed == USB_SPEED_LOW)
3216 uhci_remove_ls_ctrl(sc, upipe->ctrl.sqh);
3217 else
3218 uhci_remove_hs_ctrl(sc, upipe->ctrl.sqh);
3219
3220 if (len) {
3221 usb_syncmem(&xfer->ux_dmabuf, 0, len,
3222 isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
3223 }
3224 usb_syncmem(&upipe->ctrl.reqdma, 0,
3225 sizeof(usb_device_request_t), BUS_DMASYNC_POSTWRITE);
3226
3227 DPRINTF("length=%jd", xfer->ux_actlen, 0, 0, 0);
3228 }
3229
3230 /* Deallocate request data structures */
3231 void
3232 uhci_device_bulk_done(struct usbd_xfer *xfer)
3233 {
3234 uhci_softc_t *sc = UHCI_XFER2SC(xfer);
3235 struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe);
3236 usb_endpoint_descriptor_t *ed = xfer->ux_pipe->up_endpoint->ue_edesc;
3237 int endpt = ed->bEndpointAddress;
3238 int isread = UE_GET_DIR(endpt) == UE_DIR_IN;
3239
3240 UHCIHIST_FUNC(); UHCIHIST_CALLED();
3241 DPRINTFN(5, "xfer=%#jx sc=%#jx upipe=%#jx", (uintptr_t)xfer,
3242 (uintptr_t)sc, (uintptr_t)upipe, 0);
3243
3244 KASSERT(mutex_owned(&sc->sc_lock));
3245
3246 uhci_remove_bulk(sc, upipe->bulk.sqh);
3247
3248 if (xfer->ux_length) {
3249 usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length,
3250 isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
3251 }
3252
3253 DPRINTFN(5, "length=%jd", xfer->ux_actlen, 0, 0, 0);
3254 }
3255
3256 /* Add interrupt QH, called with vflock. */
3257 void
3258 uhci_add_intr(uhci_softc_t *sc, uhci_soft_qh_t *sqh)
3259 {
3260 struct uhci_vframe *vf = &sc->sc_vframes[sqh->pos];
3261 uhci_soft_qh_t *eqh;
3262
3263 UHCIHIST_FUNC(); UHCIHIST_CALLED();
3264 DPRINTFN(4, "n=%jd sqh=%#jx", sqh->pos, (uintptr_t)sqh, 0, 0);
3265
3266 eqh = vf->eqh;
3267 usb_syncmem(&eqh->dma, eqh->offs + offsetof(uhci_qh_t, qh_hlink),
3268 sizeof(eqh->qh.qh_hlink), BUS_DMASYNC_POSTWRITE);
3269 sqh->hlink = eqh->hlink;
3270 sqh->qh.qh_hlink = eqh->qh.qh_hlink;
3271 usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_hlink),
3272 sizeof(sqh->qh.qh_hlink), BUS_DMASYNC_PREWRITE);
3273 eqh->hlink = sqh;
3274 eqh->qh.qh_hlink = htole32(sqh->physaddr | UHCI_PTR_QH);
3275 usb_syncmem(&eqh->dma, eqh->offs + offsetof(uhci_qh_t, qh_hlink),
3276 sizeof(eqh->qh.qh_hlink), BUS_DMASYNC_PREWRITE);
3277 vf->eqh = sqh;
3278 vf->bandwidth++;
3279 }
3280
3281 /* Remove interrupt QH. */
3282 void
3283 uhci_remove_intr(uhci_softc_t *sc, uhci_soft_qh_t *sqh)
3284 {
3285 struct uhci_vframe *vf = &sc->sc_vframes[sqh->pos];
3286 uhci_soft_qh_t *pqh;
3287
3288 UHCIHIST_FUNC(); UHCIHIST_CALLED();
3289 DPRINTFN(4, "n=%jd sqh=%#jx", sqh->pos, (uintptr_t)sqh, 0, 0);
3290
3291 /* See comment in uhci_remove_ctrl() */
3292
3293 usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_elink),
3294 sizeof(sqh->qh.qh_elink),
3295 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
3296 if (!(sqh->qh.qh_elink & htole32(UHCI_PTR_T))) {
3297 sqh->qh.qh_elink = htole32(UHCI_PTR_T);
3298 usb_syncmem(&sqh->dma,
3299 sqh->offs + offsetof(uhci_qh_t, qh_elink),
3300 sizeof(sqh->qh.qh_elink),
3301 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
3302 delay(UHCI_QH_REMOVE_DELAY);
3303 }
3304
3305 pqh = uhci_find_prev_qh(vf->hqh, sqh);
3306 usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_hlink),
3307 sizeof(sqh->qh.qh_hlink),
3308 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
3309 pqh->hlink = sqh->hlink;
3310 pqh->qh.qh_hlink = sqh->qh.qh_hlink;
3311 usb_syncmem(&pqh->dma, pqh->offs + offsetof(uhci_qh_t, qh_hlink),
3312 sizeof(pqh->qh.qh_hlink),
3313 BUS_DMASYNC_PREWRITE);
3314 delay(UHCI_QH_REMOVE_DELAY);
3315 if (vf->eqh == sqh)
3316 vf->eqh = pqh;
3317 vf->bandwidth--;
3318 }
3319
3320 usbd_status
3321 uhci_device_setintr(uhci_softc_t *sc, struct uhci_pipe *upipe, int ival)
3322 {
3323 uhci_soft_qh_t *sqh;
3324 int i, npoll;
3325 u_int bestbw, bw, bestoffs, offs;
3326
3327 UHCIHIST_FUNC(); UHCIHIST_CALLED();
3328 DPRINTFN(2, "pipe=%#jx", (uintptr_t)upipe, 0, 0, 0);
3329 if (ival == 0) {
3330 printf("%s: 0 interval\n", __func__);
3331 return USBD_INVAL;
3332 }
3333
3334 if (ival > UHCI_VFRAMELIST_COUNT)
3335 ival = UHCI_VFRAMELIST_COUNT;
3336 npoll = (UHCI_VFRAMELIST_COUNT + ival - 1) / ival;
3337 DPRINTF("ival=%jd npoll=%jd", ival, npoll, 0, 0);
3338
3339 upipe->intr.npoll = npoll;
3340 upipe->intr.qhs =
3341 kmem_alloc(npoll * sizeof(uhci_soft_qh_t *), KM_SLEEP);
3342
3343 /*
3344 * Figure out which offset in the schedule that has most
3345 * bandwidth left over.
3346 */
3347 #define MOD(i) ((i) & (UHCI_VFRAMELIST_COUNT-1))
3348 for (bestoffs = offs = 0, bestbw = ~0; offs < ival; offs++) {
3349 for (bw = i = 0; i < npoll; i++)
3350 bw += sc->sc_vframes[MOD(i * ival + offs)].bandwidth;
3351 if (bw < bestbw) {
3352 bestbw = bw;
3353 bestoffs = offs;
3354 }
3355 }
3356 DPRINTF("bw=%jd offs=%jd", bestbw, bestoffs, 0, 0);
3357 for (i = 0; i < npoll; i++) {
3358 upipe->intr.qhs[i] = sqh = uhci_alloc_sqh(sc);
3359 sqh->elink = NULL;
3360 sqh->qh.qh_elink = htole32(UHCI_PTR_T);
3361 usb_syncmem(&sqh->dma,
3362 sqh->offs + offsetof(uhci_qh_t, qh_elink),
3363 sizeof(sqh->qh.qh_elink),
3364 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
3365 sqh->pos = MOD(i * ival + bestoffs);
3366 }
3367 #undef MOD
3368
3369 mutex_enter(&sc->sc_lock);
3370 /* Enter QHs into the controller data structures. */
3371 for (i = 0; i < npoll; i++)
3372 uhci_add_intr(sc, upipe->intr.qhs[i]);
3373 mutex_exit(&sc->sc_lock);
3374
3375 DPRINTFN(5, "returns %#jx", (uintptr_t)upipe, 0, 0, 0);
3376
3377 return USBD_NORMAL_COMPLETION;
3378 }
3379
3380 /* Open a new pipe. */
3381 usbd_status
3382 uhci_open(struct usbd_pipe *pipe)
3383 {
3384 uhci_softc_t *sc = UHCI_PIPE2SC(pipe);
3385 struct usbd_bus *bus = pipe->up_dev->ud_bus;
3386 struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(pipe);
3387 usb_endpoint_descriptor_t *ed = pipe->up_endpoint->ue_edesc;
3388 usbd_status err = USBD_NOMEM;
3389 int ival;
3390
3391 UHCIHIST_FUNC(); UHCIHIST_CALLED();
3392 DPRINTF("pipe=%#jx, addr=%jd, endpt=%jd (%jd)",
3393 (uintptr_t)pipe, pipe->up_dev->ud_addr, ed->bEndpointAddress,
3394 bus->ub_rhaddr);
3395
3396 if (sc->sc_dying)
3397 return USBD_IOERROR;
3398
3399 upipe->aborting = 0;
3400 /* toggle state needed for bulk endpoints */
3401 upipe->nexttoggle = pipe->up_endpoint->ue_toggle;
3402
3403 if (pipe->up_dev->ud_addr == bus->ub_rhaddr) {
3404 switch (ed->bEndpointAddress) {
3405 case USB_CONTROL_ENDPOINT:
3406 pipe->up_methods = &roothub_ctrl_methods;
3407 break;
3408 case UE_DIR_IN | USBROOTHUB_INTR_ENDPT:
3409 pipe->up_methods = &uhci_root_intr_methods;
3410 break;
3411 default:
3412 return USBD_INVAL;
3413 }
3414 } else {
3415 switch (ed->bmAttributes & UE_XFERTYPE) {
3416 case UE_CONTROL:
3417 pipe->up_methods = &uhci_device_ctrl_methods;
3418 upipe->ctrl.sqh = uhci_alloc_sqh(sc);
3419 if (upipe->ctrl.sqh == NULL)
3420 goto bad;
3421 upipe->ctrl.setup = uhci_alloc_std(sc);
3422 if (upipe->ctrl.setup == NULL) {
3423 uhci_free_sqh(sc, upipe->ctrl.sqh);
3424 goto bad;
3425 }
3426 upipe->ctrl.stat = uhci_alloc_std(sc);
3427 if (upipe->ctrl.stat == NULL) {
3428 uhci_free_sqh(sc, upipe->ctrl.sqh);
3429 uhci_free_std(sc, upipe->ctrl.setup);
3430 goto bad;
3431 }
3432 err = usb_allocmem(&sc->sc_bus,
3433 sizeof(usb_device_request_t),
3434 0, &upipe->ctrl.reqdma);
3435 if (err) {
3436 uhci_free_sqh(sc, upipe->ctrl.sqh);
3437 uhci_free_std(sc, upipe->ctrl.setup);
3438 uhci_free_std(sc, upipe->ctrl.stat);
3439 goto bad;
3440 }
3441 break;
3442 case UE_INTERRUPT:
3443 pipe->up_methods = &uhci_device_intr_methods;
3444 ival = pipe->up_interval;
3445 if (ival == USBD_DEFAULT_INTERVAL)
3446 ival = ed->bInterval;
3447 return uhci_device_setintr(sc, upipe, ival);
3448 case UE_ISOCHRONOUS:
3449 pipe->up_serialise = false;
3450 pipe->up_methods = &uhci_device_isoc_methods;
3451 return uhci_setup_isoc(pipe);
3452 case UE_BULK:
3453 pipe->up_methods = &uhci_device_bulk_methods;
3454 upipe->bulk.sqh = uhci_alloc_sqh(sc);
3455 if (upipe->bulk.sqh == NULL)
3456 goto bad;
3457 break;
3458 }
3459 }
3460 return USBD_NORMAL_COMPLETION;
3461
3462 bad:
3463 return USBD_NOMEM;
3464 }
3465
3466 /*
3467 * Data structures and routines to emulate the root hub.
3468 */
3469 /*
3470 * The USB hub protocol requires that SET_FEATURE(PORT_RESET) also
3471 * enables the port, and also states that SET_FEATURE(PORT_ENABLE)
3472 * should not be used by the USB subsystem. As we cannot issue a
3473 * SET_FEATURE(PORT_ENABLE) externally, we must ensure that the port
3474 * will be enabled as part of the reset.
3475 *
3476 * On the VT83C572, the port cannot be successfully enabled until the
3477 * outstanding "port enable change" and "connection status change"
3478 * events have been reset.
3479 */
3480 Static usbd_status
3481 uhci_portreset(uhci_softc_t *sc, int index)
3482 {
3483 int lim, port, x;
3484 UHCIHIST_FUNC(); UHCIHIST_CALLED();
3485
3486 if (index == 1)
3487 port = UHCI_PORTSC1;
3488 else if (index == 2)
3489 port = UHCI_PORTSC2;
3490 else
3491 return USBD_IOERROR;
3492
3493 x = URWMASK(UREAD2(sc, port));
3494 UWRITE2(sc, port, x | UHCI_PORTSC_PR);
3495
3496 usb_delay_ms(&sc->sc_bus, USB_PORT_ROOT_RESET_DELAY);
3497
3498 DPRINTF("uhci port %jd reset, status0 = 0x%04jx", index,
3499 UREAD2(sc, port), 0, 0);
3500
3501 x = URWMASK(UREAD2(sc, port));
3502 UWRITE2(sc, port, x & ~(UHCI_PORTSC_PR | UHCI_PORTSC_SUSP));
3503
3504 delay(100);
3505
3506 DPRINTF("uhci port %jd reset, status1 = 0x%04jx", index,
3507 UREAD2(sc, port), 0, 0);
3508
3509 x = URWMASK(UREAD2(sc, port));
3510 UWRITE2(sc, port, x | UHCI_PORTSC_PE);
3511
3512 for (lim = 10; --lim > 0;) {
3513 usb_delay_ms(&sc->sc_bus, USB_PORT_RESET_DELAY);
3514
3515 x = UREAD2(sc, port);
3516 DPRINTF("uhci port %jd iteration %ju, status = 0x%04jx", index,
3517 lim, x, 0);
3518
3519 if (!(x & UHCI_PORTSC_CCS)) {
3520 /*
3521 * No device is connected (or was disconnected
3522 * during reset). Consider the port reset.
3523 * The delay must be long enough to ensure on
3524 * the initial iteration that the device
3525 * connection will have been registered. 50ms
3526 * appears to be sufficient, but 20ms is not.
3527 */
3528 DPRINTFN(3, "uhci port %jd loop %ju, device detached",
3529 index, lim, 0, 0);
3530 break;
3531 }
3532
3533 if (x & (UHCI_PORTSC_POEDC | UHCI_PORTSC_CSC)) {
3534 /*
3535 * Port enabled changed and/or connection
3536 * status changed were set. Reset either or
3537 * both raised flags (by writing a 1 to that
3538 * bit), and wait again for state to settle.
3539 */
3540 UWRITE2(sc, port, URWMASK(x) |
3541 (x & (UHCI_PORTSC_POEDC | UHCI_PORTSC_CSC)));
3542 continue;
3543 }
3544
3545 if (x & UHCI_PORTSC_PE)
3546 /* Port is enabled */
3547 break;
3548
3549 UWRITE2(sc, port, URWMASK(x) | UHCI_PORTSC_PE);
3550 }
3551
3552 DPRINTFN(3, "uhci port %jd reset, status2 = 0x%04jx", index,
3553 UREAD2(sc, port), 0, 0);
3554
3555 if (lim <= 0) {
3556 DPRINTF("uhci port %jd reset timed out", index,
3557 0, 0, 0);
3558 return USBD_TIMEOUT;
3559 }
3560
3561 sc->sc_isreset = 1;
3562 return USBD_NORMAL_COMPLETION;
3563 }
3564
3565 Static int
3566 uhci_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req,
3567 void *buf, int buflen)
3568 {
3569 uhci_softc_t *sc = UHCI_BUS2SC(bus);
3570 int port, x;
3571 int status, change, totlen = 0;
3572 uint16_t len, value, index;
3573 usb_port_status_t ps;
3574 usbd_status err;
3575
3576 UHCIHIST_FUNC(); UHCIHIST_CALLED();
3577
3578 if (sc->sc_dying)
3579 return -1;
3580
3581 DPRINTF("type=0x%02jx request=%02jx", req->bmRequestType,
3582 req->bRequest, 0, 0);
3583
3584 len = UGETW(req->wLength);
3585 value = UGETW(req->wValue);
3586 index = UGETW(req->wIndex);
3587
3588 #define C(x,y) ((x) | ((y) << 8))
3589 switch (C(req->bRequest, req->bmRequestType)) {
3590 case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
3591 DPRINTF("wValue=0x%04jx", value, 0, 0, 0);
3592 if (len == 0)
3593 break;
3594 switch (value) {
3595 #define sd ((usb_string_descriptor_t *)buf)
3596 case C(2, UDESC_STRING):
3597 /* Product */
3598 totlen = usb_makestrdesc(sd, len, "UHCI root hub");
3599 break;
3600 #undef sd
3601 default:
3602 /* default from usbroothub */
3603 return buflen;
3604 }
3605 break;
3606
3607 /* Hub requests */
3608 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE):
3609 break;
3610 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER):
3611 DPRINTF("UR_CLEAR_PORT_FEATURE port=%jd feature=%jd", index,
3612 value, 0, 0);
3613 if (index == 1)
3614 port = UHCI_PORTSC1;
3615 else if (index == 2)
3616 port = UHCI_PORTSC2;
3617 else {
3618 return -1;
3619 }
3620 switch(value) {
3621 case UHF_PORT_ENABLE:
3622 x = URWMASK(UREAD2(sc, port));
3623 UWRITE2(sc, port, x & ~UHCI_PORTSC_PE);
3624 break;
3625 case UHF_PORT_SUSPEND:
3626 x = URWMASK(UREAD2(sc, port));
3627 if (!(x & UHCI_PORTSC_SUSP)) /* not suspended */
3628 break;
3629 UWRITE2(sc, port, x | UHCI_PORTSC_RD);
3630 /* see USB2 spec ch. 7.1.7.7 */
3631 usb_delay_ms(&sc->sc_bus, 20);
3632 UWRITE2(sc, port, x & ~UHCI_PORTSC_SUSP);
3633 /* 10ms resume delay must be provided by caller */
3634 break;
3635 case UHF_PORT_RESET:
3636 x = URWMASK(UREAD2(sc, port));
3637 UWRITE2(sc, port, x & ~UHCI_PORTSC_PR);
3638 break;
3639 case UHF_C_PORT_CONNECTION:
3640 x = URWMASK(UREAD2(sc, port));
3641 UWRITE2(sc, port, x | UHCI_PORTSC_CSC);
3642 break;
3643 case UHF_C_PORT_ENABLE:
3644 x = URWMASK(UREAD2(sc, port));
3645 UWRITE2(sc, port, x | UHCI_PORTSC_POEDC);
3646 break;
3647 case UHF_C_PORT_OVER_CURRENT:
3648 x = URWMASK(UREAD2(sc, port));
3649 UWRITE2(sc, port, x | UHCI_PORTSC_OCIC);
3650 break;
3651 case UHF_C_PORT_RESET:
3652 sc->sc_isreset = 0;
3653 break;
3654 case UHF_PORT_CONNECTION:
3655 case UHF_PORT_OVER_CURRENT:
3656 case UHF_PORT_POWER:
3657 case UHF_PORT_LOW_SPEED:
3658 case UHF_C_PORT_SUSPEND:
3659 default:
3660 return -1;
3661 }
3662 break;
3663 case C(UR_GET_BUS_STATE, UT_READ_CLASS_OTHER):
3664 if (index == 1)
3665 port = UHCI_PORTSC1;
3666 else if (index == 2)
3667 port = UHCI_PORTSC2;
3668 else {
3669 return -1;
3670 }
3671 if (len > 0) {
3672 *(uint8_t *)buf =
3673 UHCI_PORTSC_GET_LS(UREAD2(sc, port));
3674 totlen = 1;
3675 }
3676 break;
3677 case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
3678 if (len == 0)
3679 break;
3680 if ((value & 0xff) != 0) {
3681 return -1;
3682 }
3683 usb_hub_descriptor_t hubd;
3684
3685 totlen = uimin(buflen, sizeof(hubd));
3686 memcpy(&hubd, buf, totlen);
3687 hubd.bNbrPorts = 2;
3688 memcpy(buf, &hubd, totlen);
3689 break;
3690 case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
3691 if (len != 4) {
3692 return -1;
3693 }
3694 memset(buf, 0, len);
3695 totlen = len;
3696 break;
3697 case C(UR_GET_STATUS, UT_READ_CLASS_OTHER):
3698 if (index == 1)
3699 port = UHCI_PORTSC1;
3700 else if (index == 2)
3701 port = UHCI_PORTSC2;
3702 else {
3703 return -1;
3704 }
3705 if (len != 4) {
3706 return -1;
3707 }
3708 x = UREAD2(sc, port);
3709 status = change = 0;
3710 if (x & UHCI_PORTSC_CCS)
3711 status |= UPS_CURRENT_CONNECT_STATUS;
3712 if (x & UHCI_PORTSC_CSC)
3713 change |= UPS_C_CONNECT_STATUS;
3714 if (x & UHCI_PORTSC_PE)
3715 status |= UPS_PORT_ENABLED;
3716 if (x & UHCI_PORTSC_POEDC)
3717 change |= UPS_C_PORT_ENABLED;
3718 if (x & UHCI_PORTSC_OCI)
3719 status |= UPS_OVERCURRENT_INDICATOR;
3720 if (x & UHCI_PORTSC_OCIC)
3721 change |= UPS_C_OVERCURRENT_INDICATOR;
3722 if (x & UHCI_PORTSC_SUSP)
3723 status |= UPS_SUSPEND;
3724 if (x & UHCI_PORTSC_LSDA)
3725 status |= UPS_LOW_SPEED;
3726 status |= UPS_PORT_POWER;
3727 if (sc->sc_isreset)
3728 change |= UPS_C_PORT_RESET;
3729 USETW(ps.wPortStatus, status);
3730 USETW(ps.wPortChange, change);
3731 totlen = uimin(len, sizeof(ps));
3732 memcpy(buf, &ps, totlen);
3733 break;
3734 case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
3735 return -1;
3736 case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE):
3737 break;
3738 case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER):
3739 if (index == 1)
3740 port = UHCI_PORTSC1;
3741 else if (index == 2)
3742 port = UHCI_PORTSC2;
3743 else {
3744 return -1;
3745 }
3746 switch(value) {
3747 case UHF_PORT_ENABLE:
3748 x = URWMASK(UREAD2(sc, port));
3749 UWRITE2(sc, port, x | UHCI_PORTSC_PE);
3750 break;
3751 case UHF_PORT_SUSPEND:
3752 x = URWMASK(UREAD2(sc, port));
3753 UWRITE2(sc, port, x | UHCI_PORTSC_SUSP);
3754 break;
3755 case UHF_PORT_RESET:
3756 err = uhci_portreset(sc, index);
3757 if (err != USBD_NORMAL_COMPLETION)
3758 return -1;
3759 return 0;
3760 case UHF_PORT_POWER:
3761 /* Pretend we turned on power */
3762 return 0;
3763 case UHF_C_PORT_CONNECTION:
3764 case UHF_C_PORT_ENABLE:
3765 case UHF_C_PORT_OVER_CURRENT:
3766 case UHF_PORT_CONNECTION:
3767 case UHF_PORT_OVER_CURRENT:
3768 case UHF_PORT_LOW_SPEED:
3769 case UHF_C_PORT_SUSPEND:
3770 case UHF_C_PORT_RESET:
3771 default:
3772 return -1;
3773 }
3774 break;
3775 default:
3776 /* default from usbroothub */
3777 DPRINTF("returning %jd (usbroothub default)",
3778 buflen, 0, 0, 0);
3779 return buflen;
3780 }
3781
3782 DPRINTF("returning %jd", totlen, 0, 0, 0);
3783
3784 return totlen;
3785 }
3786
3787 /* Abort a root interrupt request. */
3788 void
3789 uhci_root_intr_abort(struct usbd_xfer *xfer)
3790 {
3791 uhci_softc_t *sc = UHCI_XFER2SC(xfer);
3792
3793 KASSERT(mutex_owned(&sc->sc_lock));
3794 KASSERT(xfer->ux_pipe->up_intrxfer == xfer);
3795
3796 callout_stop(&sc->sc_poll_handle);
3797 sc->sc_intr_xfer = NULL;
3798
3799 xfer->ux_status = USBD_CANCELLED;
3800 #ifdef DIAGNOSTIC
3801 UHCI_XFER2UXFER(xfer)->ux_isdone = true;
3802 #endif
3803 usb_transfer_complete(xfer);
3804 }
3805
3806 usbd_status
3807 uhci_root_intr_transfer(struct usbd_xfer *xfer)
3808 {
3809 uhci_softc_t *sc = UHCI_XFER2SC(xfer);
3810 usbd_status err;
3811
3812 /* Insert last in queue. */
3813 mutex_enter(&sc->sc_lock);
3814 err = usb_insert_transfer(xfer);
3815 mutex_exit(&sc->sc_lock);
3816 if (err)
3817 return err;
3818
3819 /*
3820 * Pipe isn't running (otherwise err would be USBD_INPROG),
3821 * start first
3822 */
3823 return uhci_root_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue));
3824 }
3825
3826 /* Start a transfer on the root interrupt pipe */
3827 usbd_status
3828 uhci_root_intr_start(struct usbd_xfer *xfer)
3829 {
3830 struct usbd_pipe *pipe = xfer->ux_pipe;
3831 uhci_softc_t *sc = UHCI_PIPE2SC(pipe);
3832 unsigned int ival;
3833
3834 UHCIHIST_FUNC(); UHCIHIST_CALLED();
3835 DPRINTF("xfer=%#jx len=%jd flags=%jd", (uintptr_t)xfer, xfer->ux_length,
3836 xfer->ux_flags, 0);
3837
3838 if (sc->sc_dying)
3839 return USBD_IOERROR;
3840
3841 /* XXX temporary variable needed to avoid gcc3 warning */
3842 ival = xfer->ux_pipe->up_endpoint->ue_edesc->bInterval;
3843 sc->sc_ival = mstohz(ival);
3844 callout_reset(&sc->sc_poll_handle, sc->sc_ival, uhci_poll_hub, xfer);
3845 sc->sc_intr_xfer = xfer;
3846 return USBD_IN_PROGRESS;
3847 }
3848
3849 /* Close the root interrupt pipe. */
3850 void
3851 uhci_root_intr_close(struct usbd_pipe *pipe)
3852 {
3853 uhci_softc_t *sc = UHCI_PIPE2SC(pipe);
3854 UHCIHIST_FUNC(); UHCIHIST_CALLED();
3855
3856 KASSERT(mutex_owned(&sc->sc_lock));
3857
3858 callout_stop(&sc->sc_poll_handle);
3859 sc->sc_intr_xfer = NULL;
3860 }
3861