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