uhci.c revision 1.85 1 /* $NetBSD: uhci.c,v 1.85 2000/02/22 11:30:55 augustss Exp $ */
2 /* $FreeBSD: src/sys/dev/usb/uhci.c,v 1.33 1999/11/17 22:33:41 n_hibma Exp $ */
3
4 /*
5 * Copyright (c) 1998 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Lennart Augustsson (augustss (at) carlstedt.se) at
10 * Carlstedt Research & Technology.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. All advertising materials mentioning features or use of this software
21 * must display the following acknowledgement:
22 * This product includes software developed by the NetBSD
23 * Foundation, Inc. and its contributors.
24 * 4. Neither the name of The NetBSD Foundation nor the names of its
25 * contributors may be used to endorse or promote products derived
26 * from this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
29 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
32 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGE.
39 */
40
41 /*
42 * USB Universal Host Controller driver.
43 * Handles e.g. PIIX3 and PIIX4.
44 *
45 * UHCI spec: http://www.intel.com/design/usb/uhci11d.pdf
46 * USB spec: http://www.usb.org/developers/data/usb11.pdf
47 * PIIXn spec: ftp://download.intel.com/design/intarch/datashts/29055002.pdf
48 * ftp://download.intel.com/design/intarch/datashts/29056201.pdf
49 */
50
51 #include <sys/param.h>
52 #include <sys/systm.h>
53 #include <sys/kernel.h>
54 #include <sys/malloc.h>
55 #if defined(__NetBSD__) || defined(__OpenBSD__)
56 #include <sys/device.h>
57 #include <sys/select.h>
58 #elif defined(__FreeBSD__)
59 #include <sys/module.h>
60 #include <sys/bus.h>
61 #include <machine/bus_pio.h>
62 #if defined(DIAGNOSTIC) && defined(__i386__)
63 #include <machine/cpu.h>
64 #endif
65 #endif
66 #include <sys/proc.h>
67 #include <sys/queue.h>
68
69 #include <machine/bus.h>
70 #include <machine/endian.h>
71
72 #include <dev/usb/usb.h>
73 #include <dev/usb/usbdi.h>
74 #include <dev/usb/usbdivar.h>
75 #include <dev/usb/usb_mem.h>
76 #include <dev/usb/usb_quirks.h>
77
78 #include <dev/usb/uhcireg.h>
79 #include <dev/usb/uhcivar.h>
80
81 #if defined(__FreeBSD__)
82 #include <machine/clock.h>
83
84 #define delay(d) DELAY(d)
85 #endif
86
87 #define MS_TO_TICKS(ms) ((ms) * hz / 1000)
88
89 #if defined(__OpenBSD__)
90 struct cfdriver uhci_cd = {
91 NULL, "uhci", DV_DULL
92 };
93 #endif
94
95 #ifdef UHCI_DEBUG
96 #define DPRINTF(x) if (uhcidebug) printf x
97 #define DPRINTFN(n,x) if (uhcidebug>(n)) printf x
98 int uhcidebug = 0;
99 #else
100 #define DPRINTF(x)
101 #define DPRINTFN(n,x)
102 #endif
103
104 /*
105 * The UHCI controller is little endian, so on big endian machines
106 * the data strored in memory needs to be swapped.
107 */
108 #if BYTE_ORDER == BIG_ENDIAN
109 #define LE(x) (bswap32(x))
110 #else
111 #define LE(x) (x)
112 #endif
113
114 struct uhci_pipe {
115 struct usbd_pipe pipe;
116 uhci_intr_info_t *iinfo;
117 int nexttoggle;
118 /* Info needed for different pipe kinds. */
119 union {
120 /* Control pipe */
121 struct {
122 uhci_soft_qh_t *sqh;
123 usb_dma_t reqdma;
124 uhci_soft_td_t *setup, *stat;
125 u_int length;
126 } ctl;
127 /* Interrupt pipe */
128 struct {
129 int npoll;
130 uhci_soft_qh_t **qhs;
131 } intr;
132 /* Bulk pipe */
133 struct {
134 uhci_soft_qh_t *sqh;
135 u_int length;
136 int isread;
137 } bulk;
138 /* Iso pipe */
139 struct iso {
140 uhci_soft_td_t **stds;
141 int next, inuse;
142 } iso;
143 } u;
144 };
145
146 /*
147 * The uhci_intr_info free list can be global since they contain
148 * no dma specific data. The other free lists do.
149 */
150 LIST_HEAD(, uhci_intr_info) uhci_ii_free;
151
152 static void uhci_busreset __P((uhci_softc_t *));
153 static void uhci_shutdown __P((void *v));
154 static void uhci_power __P((int, void *));
155 static usbd_status uhci_run __P((uhci_softc_t *, int run));
156 static uhci_soft_td_t *uhci_alloc_std __P((uhci_softc_t *));
157 static void uhci_free_std __P((uhci_softc_t *, uhci_soft_td_t *));
158 static uhci_soft_qh_t *uhci_alloc_sqh __P((uhci_softc_t *));
159 static void uhci_free_sqh __P((uhci_softc_t *, uhci_soft_qh_t *));
160 static uhci_intr_info_t *uhci_alloc_intr_info __P((uhci_softc_t *));
161 static void uhci_free_intr_info __P((uhci_intr_info_t *ii));
162 #if 0
163 static void uhci_enter_ctl_q __P((uhci_softc_t *, uhci_soft_qh_t *,
164 uhci_intr_info_t *));
165 static void uhci_exit_ctl_q __P((uhci_softc_t *, uhci_soft_qh_t *));
166 #endif
167
168 static void uhci_free_std_chain __P((uhci_softc_t *,
169 uhci_soft_td_t *, uhci_soft_td_t *));
170 static usbd_status uhci_alloc_std_chain __P((struct uhci_pipe *,
171 uhci_softc_t *, int, int, u_int16_t, usb_dma_t *,
172 uhci_soft_td_t **, uhci_soft_td_t **));
173 static void uhci_timo __P((void *));
174 static void uhci_waitintr __P((uhci_softc_t *,
175 usbd_xfer_handle));
176 static void uhci_check_intr __P((uhci_softc_t *,
177 uhci_intr_info_t *));
178 static void uhci_idone __P((uhci_intr_info_t *));
179 static void uhci_abort_xfer __P((usbd_xfer_handle,
180 usbd_status status));
181 static void uhci_abort_xfer_end __P((void *v));
182 static void uhci_timeout __P((void *));
183 static void uhci_lock_frames __P((uhci_softc_t *));
184 static void uhci_unlock_frames __P((uhci_softc_t *));
185 static void uhci_add_ctrl __P((uhci_softc_t *, uhci_soft_qh_t *));
186 static void uhci_add_bulk __P((uhci_softc_t *, uhci_soft_qh_t *));
187 static void uhci_remove_ctrl __P((uhci_softc_t *,uhci_soft_qh_t *));
188 static void uhci_remove_bulk __P((uhci_softc_t *,uhci_soft_qh_t *));
189 static int uhci_str __P((usb_string_descriptor_t *, int, char *));
190
191 static usbd_status uhci_setup_isoc __P((usbd_pipe_handle pipe));
192 static void uhci_device_isoc_enter __P((usbd_xfer_handle));
193
194 static usbd_status uhci_allocm __P((struct usbd_bus *, usb_dma_t *,
195 u_int32_t));
196 static void uhci_freem __P((struct usbd_bus *, usb_dma_t *));
197
198 static usbd_xfer_handle uhci_allocx __P((struct usbd_bus *));
199 static void uhci_freex __P((struct usbd_bus *, usbd_xfer_handle));
200
201 static usbd_status uhci_device_ctrl_transfer __P((usbd_xfer_handle));
202 static usbd_status uhci_device_ctrl_start __P((usbd_xfer_handle));
203 static void uhci_device_ctrl_abort __P((usbd_xfer_handle));
204 static void uhci_device_ctrl_close __P((usbd_pipe_handle));
205 static void uhci_device_ctrl_done __P((usbd_xfer_handle));
206
207 static usbd_status uhci_device_intr_transfer __P((usbd_xfer_handle));
208 static usbd_status uhci_device_intr_start __P((usbd_xfer_handle));
209 static void uhci_device_intr_abort __P((usbd_xfer_handle));
210 static void uhci_device_intr_close __P((usbd_pipe_handle));
211 static void uhci_device_intr_done __P((usbd_xfer_handle));
212
213 static usbd_status uhci_device_bulk_transfer __P((usbd_xfer_handle));
214 static usbd_status uhci_device_bulk_start __P((usbd_xfer_handle));
215 static void uhci_device_bulk_abort __P((usbd_xfer_handle));
216 static void uhci_device_bulk_close __P((usbd_pipe_handle));
217 static void uhci_device_bulk_done __P((usbd_xfer_handle));
218
219 static usbd_status uhci_device_isoc_transfer __P((usbd_xfer_handle));
220 static usbd_status uhci_device_isoc_start __P((usbd_xfer_handle));
221 static void uhci_device_isoc_abort __P((usbd_xfer_handle));
222 static void uhci_device_isoc_close __P((usbd_pipe_handle));
223 static void uhci_device_isoc_done __P((usbd_xfer_handle));
224
225 static usbd_status uhci_root_ctrl_transfer __P((usbd_xfer_handle));
226 static usbd_status uhci_root_ctrl_start __P((usbd_xfer_handle));
227 static void uhci_root_ctrl_abort __P((usbd_xfer_handle));
228 static void uhci_root_ctrl_close __P((usbd_pipe_handle));
229 static void uhci_root_ctrl_done __P((usbd_xfer_handle));
230
231 static usbd_status uhci_root_intr_transfer __P((usbd_xfer_handle));
232 static usbd_status uhci_root_intr_start __P((usbd_xfer_handle));
233 static void uhci_root_intr_abort __P((usbd_xfer_handle));
234 static void uhci_root_intr_close __P((usbd_pipe_handle));
235 static void uhci_root_intr_done __P((usbd_xfer_handle));
236
237 static usbd_status uhci_open __P((usbd_pipe_handle));
238 static void uhci_poll __P((struct usbd_bus *));
239 static void uhci_softintr __P((struct usbd_bus *));
240
241 static usbd_status uhci_device_request __P((usbd_xfer_handle xfer));
242
243 static void uhci_add_intr __P((uhci_softc_t *, int,
244 uhci_soft_qh_t *));
245 static void uhci_remove_intr __P((uhci_softc_t *, int,
246 uhci_soft_qh_t *));
247 static usbd_status uhci_device_setintr __P((uhci_softc_t *sc,
248 struct uhci_pipe *pipe, int ival));
249
250 static void uhci_device_clear_toggle __P((usbd_pipe_handle pipe));
251 static void uhci_noop __P((usbd_pipe_handle pipe));
252
253 #ifdef UHCI_DEBUG
254 static void uhci_dumpregs __P((uhci_softc_t *));
255 static void uhci_dump_qhs __P((uhci_soft_qh_t *));
256 static void uhci_dump_qh __P((uhci_soft_qh_t *));
257 static void uhci_dump_tds __P((uhci_soft_td_t *));
258 static void uhci_dump_td __P((uhci_soft_td_t *));
259 #endif
260
261 #define UWRITE2(sc, r, x) bus_space_write_2((sc)->iot, (sc)->ioh, (r), (x))
262 #define UWRITE4(sc, r, x) bus_space_write_4((sc)->iot, (sc)->ioh, (r), (x))
263 #define UREAD1(sc, r) bus_space_read_1((sc)->iot, (sc)->ioh, (r))
264 #define UREAD2(sc, r) bus_space_read_2((sc)->iot, (sc)->ioh, (r))
265 #define UREAD4(sc, r) bus_space_read_4((sc)->iot, (sc)->ioh, (r))
266
267 #define UHCICMD(sc, cmd) UWRITE2(sc, UHCI_CMD, cmd)
268 #define UHCISTS(sc) UREAD2(sc, UHCI_STS)
269
270 #define UHCI_RESET_TIMEOUT 100 /* reset timeout */
271
272 #define UHCI_CURFRAME(sc) (UREAD2(sc, UHCI_FRNUM) & UHCI_FRNUM_MASK)
273
274 #define UHCI_INTR_ENDPT 1
275
276 struct usbd_bus_methods uhci_bus_methods = {
277 uhci_open,
278 uhci_softintr,
279 uhci_poll,
280 uhci_allocm,
281 uhci_freem,
282 uhci_allocx,
283 uhci_freex,
284 };
285
286 struct usbd_pipe_methods uhci_root_ctrl_methods = {
287 uhci_root_ctrl_transfer,
288 uhci_root_ctrl_start,
289 uhci_root_ctrl_abort,
290 uhci_root_ctrl_close,
291 uhci_noop,
292 uhci_root_ctrl_done,
293 };
294
295 struct usbd_pipe_methods uhci_root_intr_methods = {
296 uhci_root_intr_transfer,
297 uhci_root_intr_start,
298 uhci_root_intr_abort,
299 uhci_root_intr_close,
300 uhci_noop,
301 uhci_root_intr_done,
302 };
303
304 struct usbd_pipe_methods uhci_device_ctrl_methods = {
305 uhci_device_ctrl_transfer,
306 uhci_device_ctrl_start,
307 uhci_device_ctrl_abort,
308 uhci_device_ctrl_close,
309 uhci_noop,
310 uhci_device_ctrl_done,
311 };
312
313 struct usbd_pipe_methods uhci_device_intr_methods = {
314 uhci_device_intr_transfer,
315 uhci_device_intr_start,
316 uhci_device_intr_abort,
317 uhci_device_intr_close,
318 uhci_device_clear_toggle,
319 uhci_device_intr_done,
320 };
321
322 struct usbd_pipe_methods uhci_device_bulk_methods = {
323 uhci_device_bulk_transfer,
324 uhci_device_bulk_start,
325 uhci_device_bulk_abort,
326 uhci_device_bulk_close,
327 uhci_device_clear_toggle,
328 uhci_device_bulk_done,
329 };
330
331 struct usbd_pipe_methods uhci_device_isoc_methods = {
332 uhci_device_isoc_transfer,
333 uhci_device_isoc_start,
334 uhci_device_isoc_abort,
335 uhci_device_isoc_close,
336 uhci_noop,
337 uhci_device_isoc_done,
338 };
339
340 void
341 uhci_busreset(sc)
342 uhci_softc_t *sc;
343 {
344 UHCICMD(sc, UHCI_CMD_GRESET); /* global reset */
345 usb_delay_ms(&sc->sc_bus, USB_BUS_RESET_DELAY); /* wait a little */
346 UHCICMD(sc, 0); /* do nothing */
347 }
348
349 usbd_status
350 uhci_init(sc)
351 uhci_softc_t *sc;
352 {
353 usbd_status err;
354 int i, j;
355 uhci_soft_qh_t *csqh, *bsqh, *sqh;
356 uhci_soft_td_t *std;
357
358 DPRINTFN(1,("uhci_init: start\n"));
359
360 #ifdef UHCI_DEBUG
361 if (uhcidebug > 2)
362 uhci_dumpregs(sc);
363 #endif
364
365 uhci_run(sc, 0); /* stop the controller */
366 UWRITE2(sc, UHCI_INTR, 0); /* disable interrupts */
367
368 uhci_busreset(sc);
369
370 /* Allocate and initialize real frame array. */
371 err = usb_allocmem(&sc->sc_bus,
372 UHCI_FRAMELIST_COUNT * sizeof(uhci_physaddr_t),
373 UHCI_FRAMELIST_ALIGN, &sc->sc_dma);
374 if (err)
375 return (err);
376 sc->sc_pframes = KERNADDR(&sc->sc_dma);
377 UWRITE2(sc, UHCI_FRNUM, 0); /* set frame number to 0 */
378 UWRITE4(sc, UHCI_FLBASEADDR, DMAADDR(&sc->sc_dma)); /* set frame list*/
379
380 /* Allocate the dummy QH where bulk traffic will be queued. */
381 bsqh = uhci_alloc_sqh(sc);
382 if (bsqh == NULL)
383 return (USBD_NOMEM);
384 bsqh->qh.qh_hlink = LE(UHCI_PTR_T); /* end of QH chain */
385 bsqh->qh.qh_elink = LE(UHCI_PTR_T);
386 sc->sc_bulk_start = sc->sc_bulk_end = bsqh;
387
388 /* Allocate the dummy QH where control traffic will be queued. */
389 csqh = uhci_alloc_sqh(sc);
390 if (csqh == NULL)
391 return (USBD_NOMEM);
392 csqh->hlink = bsqh;
393 csqh->qh.qh_hlink = LE(bsqh->physaddr | UHCI_PTR_Q);
394 csqh->qh.qh_elink = LE(UHCI_PTR_T);
395 sc->sc_ctl_start = sc->sc_ctl_end = csqh;
396
397 /*
398 * Make all (virtual) frame list pointers point to the interrupt
399 * queue heads and the interrupt queue heads at the control
400 * queue head and point the physical frame list to the virtual.
401 */
402 for(i = 0; i < UHCI_VFRAMELIST_COUNT; i++) {
403 std = uhci_alloc_std(sc);
404 sqh = uhci_alloc_sqh(sc);
405 if (std == NULL || sqh == NULL)
406 return (USBD_NOMEM);
407 std->link.sqh = sqh;
408 std->td.td_link = LE(sqh->physaddr | UHCI_PTR_Q);
409 std->td.td_status = LE(UHCI_TD_IOS); /* iso, inactive */
410 std->td.td_token = LE(0);
411 std->td.td_buffer = LE(0);
412 sqh->hlink = csqh;
413 sqh->qh.qh_hlink = LE(csqh->physaddr | UHCI_PTR_Q);
414 sqh->elink = 0;
415 sqh->qh.qh_elink = LE(UHCI_PTR_T);
416 sc->sc_vframes[i].htd = std;
417 sc->sc_vframes[i].etd = std;
418 sc->sc_vframes[i].hqh = sqh;
419 sc->sc_vframes[i].eqh = sqh;
420 for (j = i;
421 j < UHCI_FRAMELIST_COUNT;
422 j += UHCI_VFRAMELIST_COUNT)
423 sc->sc_pframes[j] = LE(std->physaddr);
424 }
425
426 LIST_INIT(&sc->sc_intrhead);
427
428 SIMPLEQ_INIT(&sc->sc_free_xfers);
429
430 /* Set up the bus struct. */
431 sc->sc_bus.methods = &uhci_bus_methods;
432 sc->sc_bus.pipe_size = sizeof(struct uhci_pipe);
433
434 sc->sc_suspend = PWR_RESUME;
435 sc->sc_powerhook = powerhook_establish(uhci_power, sc);
436
437 sc->sc_shutdownhook = shutdownhook_establish(uhci_shutdown, sc);
438
439 DPRINTFN(1,("uhci_init: enabling\n"));
440 UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE | UHCI_INTR_RIE |
441 UHCI_INTR_IOCE | UHCI_INTR_SPIE); /* enable interrupts */
442
443 UHCICMD(sc, UHCI_CMD_MAXP); /* Assume 64 byte packets at frame end */
444
445 return (uhci_run(sc, 1)); /* and here we go... */
446 }
447
448 #if defined(__NetBSD__) || defined(__OpenBSD__)
449 int
450 uhci_activate(self, act)
451 device_ptr_t self;
452 enum devact act;
453 {
454 struct uhci_softc *sc = (struct uhci_softc *)self;
455 int rv = 0;
456
457 switch (act) {
458 case DVACT_ACTIVATE:
459 return (EOPNOTSUPP);
460 break;
461
462 case DVACT_DEACTIVATE:
463 if (sc->sc_child != NULL)
464 rv = config_deactivate(sc->sc_child);
465 break;
466 }
467 return (rv);
468 }
469
470 int
471 uhci_detach(sc, flags)
472 struct uhci_softc *sc;
473 int flags;
474 {
475 usbd_xfer_handle xfer;
476 int rv = 0;
477
478 if (sc->sc_child != NULL)
479 rv = config_detach(sc->sc_child, flags);
480
481 if (rv != 0)
482 return (rv);
483
484 powerhook_disestablish(sc->sc_powerhook);
485 shutdownhook_disestablish(sc->sc_shutdownhook);
486
487 /* Free all xfers associated with this HC. */
488 for (;;) {
489 xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers);
490 if (xfer == NULL)
491 break;
492 SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, xfer, next);
493 free(xfer, M_USB);
494 }
495
496 /* XXX free other data structures XXX */
497
498 return (rv);
499 }
500 #endif
501
502 usbd_status
503 uhci_allocm(bus, dma, size)
504 struct usbd_bus *bus;
505 usb_dma_t *dma;
506 u_int32_t size;
507 {
508 return (usb_allocmem(&((struct uhci_softc *)bus)->sc_bus, size, 0,
509 dma));
510 }
511
512 void
513 uhci_freem(bus, dma)
514 struct usbd_bus *bus;
515 usb_dma_t *dma;
516 {
517 usb_freemem(&((struct uhci_softc *)bus)->sc_bus, dma);
518 }
519
520 usbd_xfer_handle
521 uhci_allocx(bus)
522 struct usbd_bus *bus;
523 {
524 struct uhci_softc *sc = (struct uhci_softc *)bus;
525 usbd_xfer_handle xfer;
526
527 xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers);
528 if (xfer != NULL)
529 SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, xfer, next);
530 else
531 xfer = malloc(sizeof(*xfer), M_USB, M_NOWAIT);
532 if (xfer != NULL)
533 memset(xfer, 0, sizeof *xfer);
534 return (xfer);
535 }
536
537 void
538 uhci_freex(bus, xfer)
539 struct usbd_bus *bus;
540 usbd_xfer_handle xfer;
541 {
542 struct uhci_softc *sc = (struct uhci_softc *)bus;
543
544 SIMPLEQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next);
545 }
546
547 /*
548 * Shut down the controller when the system is going down.
549 */
550 void
551 uhci_shutdown(v)
552 void *v;
553 {
554 uhci_softc_t *sc = v;
555
556 DPRINTF(("uhci_shutdown: stopping the HC\n"));
557 uhci_run(sc, 0); /* stop the controller */
558 }
559
560 /*
561 * Handle suspend/resume.
562 *
563 * We need to switch to polling mode here, because this routine is
564 * called from an intterupt context. This is all right since we
565 * are almost suspended anyway.
566 */
567 void
568 uhci_power(why, v)
569 int why;
570 void *v;
571 {
572 uhci_softc_t *sc = v;
573 int cmd;
574 int s;
575
576 s = splusb();
577 cmd = UREAD2(sc, UHCI_CMD);
578
579 DPRINTF(("uhci_power: sc=%p, why=%d (was %d), cmd=0x%x\n",
580 sc, why, sc->sc_suspend, cmd));
581
582 if (why != PWR_RESUME) {
583 #ifdef UHCI_DEBUG
584 if (uhcidebug > 2)
585 uhci_dumpregs(sc);
586 #endif
587 if (sc->sc_has_timo != NULL)
588 usb_untimeout(uhci_timo, sc->sc_has_timo,
589 sc->sc_has_timo->timo_handle);
590 sc->sc_bus.use_polling++;
591 uhci_run(sc, 0); /* stop the controller */
592 UHCICMD(sc, cmd | UHCI_CMD_EGSM); /* enter global suspend */
593 usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT);
594 sc->sc_suspend = why;
595 sc->sc_bus.use_polling--;
596 DPRINTF(("uhci_power: cmd=0x%x\n", UREAD2(sc, UHCI_CMD)));
597 } else {
598 /*
599 * XXX We should really do much more here in case the
600 * controller registers have been lost and BIOS has
601 * not restored them.
602 */
603 #ifdef DIAGNOSTIC
604 if (sc->sc_suspend == PWR_RESUME)
605 printf("uhci_power: weird, resume without suspend.\n");
606 #endif
607 sc->sc_bus.use_polling++;
608 sc->sc_suspend = why;
609 if (cmd & UHCI_CMD_RS)
610 uhci_run(sc, 0); /* in case BIOS has started it */
611 UHCICMD(sc, cmd | UHCI_CMD_FGR); /* force global resume */
612 usb_delay_ms(&sc->sc_bus, USB_RESUME_DELAY);
613 UHCICMD(sc, cmd & ~UHCI_CMD_EGSM); /* back to normal */
614 UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE | UHCI_INTR_RIE |
615 UHCI_INTR_IOCE | UHCI_INTR_SPIE); /* re-enable intrs */
616 uhci_run(sc, 1); /* and start traffic again */
617 usb_delay_ms(&sc->sc_bus, USB_RESUME_RECOVERY);
618 sc->sc_bus.use_polling--;
619 if (sc->sc_has_timo != NULL)
620 usb_timeout(uhci_timo, sc->sc_has_timo,
621 sc->sc_ival, sc->sc_has_timo->timo_handle);
622 #ifdef UHCI_DEBUG
623 if (uhcidebug > 2)
624 uhci_dumpregs(sc);
625 #endif
626 }
627 splx(s);
628 }
629
630 #ifdef UHCI_DEBUG
631 static void
632 uhci_dumpregs(sc)
633 uhci_softc_t *sc;
634 {
635 DPRINTFN(-1,("%s regs: cmd=%04x, sts=%04x, intr=%04x, frnum=%04x, "
636 "flbase=%08x, sof=%04x, portsc1=%04x, portsc2=%04x\n",
637 USBDEVNAME(sc->sc_bus.bdev),
638 UREAD2(sc, UHCI_CMD),
639 UREAD2(sc, UHCI_STS),
640 UREAD2(sc, UHCI_INTR),
641 UREAD2(sc, UHCI_FRNUM),
642 UREAD4(sc, UHCI_FLBASEADDR),
643 UREAD1(sc, UHCI_SOF),
644 UREAD2(sc, UHCI_PORTSC1),
645 UREAD2(sc, UHCI_PORTSC2)));
646 }
647
648 void
649 uhci_dump_td(p)
650 uhci_soft_td_t *p;
651 {
652 DPRINTFN(-1,("TD(%p) at %08lx = link=0x%08lx status=0x%08lx "
653 "token=0x%08lx buffer=0x%08lx\n",
654 p, (long)p->physaddr,
655 (long)LE(p->td.td_link),
656 (long)LE(p->td.td_status),
657 (long)LE(p->td.td_token),
658 (long)LE(p->td.td_buffer)));
659 DPRINTFN(-1,(" %b %b,errcnt=%d,actlen=%d pid=%02x,addr=%d,endpt=%d,"
660 "D=%d,maxlen=%d\n",
661 (int)LE(p->td.td_link),
662 "\20\1T\2Q\3VF",
663 (int)LE(p->td.td_status),
664 "\20\22BITSTUFF\23CRCTO\24NAK\25BABBLE\26DBUFFER\27"
665 "STALLED\30ACTIVE\31IOC\32ISO\33LS\36SPD",
666 UHCI_TD_GET_ERRCNT(LE(p->td.td_status)),
667 UHCI_TD_GET_ACTLEN(LE(p->td.td_status)),
668 UHCI_TD_GET_PID(LE(p->td.td_token)),
669 UHCI_TD_GET_DEVADDR(LE(p->td.td_token)),
670 UHCI_TD_GET_ENDPT(LE(p->td.td_token)),
671 UHCI_TD_GET_DT(LE(p->td.td_token)),
672 UHCI_TD_GET_MAXLEN(LE(p->td.td_token))));
673 }
674
675 void
676 uhci_dump_qh(sqh)
677 uhci_soft_qh_t *sqh;
678 {
679 DPRINTFN(-1,("QH(%p) at %08x: hlink=%08x elink=%08x\n", sqh,
680 (int)sqh->physaddr, LE(sqh->qh.qh_hlink), LE(sqh->qh.qh_elink)));
681 }
682
683
684 #if 0
685 void
686 uhci_dump()
687 {
688 uhci_softc_t *sc = uhci;
689
690 uhci_dumpregs(sc);
691 printf("intrs=%d\n", sc->sc_bus.no_intrs);
692 printf("framelist[i].link = %08x\n", sc->sc_framelist[0].link);
693 uhci_dump_qh(sc->sc_ctl_start->qh.hlink);
694 }
695 #endif
696
697
698 void
699 uhci_dump_qhs(sqh)
700 uhci_soft_qh_t *sqh;
701 {
702 uhci_dump_qh(sqh);
703
704 /* uhci_dump_qhs displays all the QHs and TDs from the given QH onwards
705 * Traverses sideways first, then down.
706 *
707 * QH1
708 * QH2
709 * No QH
710 * TD2.1
711 * TD2.2
712 * TD1.1
713 * etc.
714 *
715 * TD2.x being the TDs queued at QH2 and QH1 being referenced from QH1.
716 */
717
718
719 if (sqh->hlink != NULL && !(sqh->qh.qh_hlink & UHCI_PTR_T))
720 uhci_dump_qhs(sqh->hlink);
721 else
722 DPRINTF(("No QH\n"));
723
724 if (sqh->elink != NULL && !(sqh->qh.qh_elink & UHCI_PTR_T))
725 uhci_dump_tds(sqh->elink);
726 else
727 DPRINTF(("No TD\n"));
728 }
729
730 void
731 uhci_dump_tds(std)
732 uhci_soft_td_t *std;
733 {
734 uhci_soft_td_t *td;
735
736 for(td = std; td != NULL; td = td->link.std) {
737 uhci_dump_td(td);
738
739 /* Check whether the link pointer in this TD marks
740 * the link pointer as end of queue. This avoids
741 * printing the free list in case the queue/TD has
742 * already been moved there (seatbelt).
743 */
744 if (td->td.td_link & UHCI_PTR_T ||
745 td->td.td_link == 0)
746 break;
747 }
748 }
749 #endif
750
751 /*
752 * This routine is executed periodically and simulates interrupts
753 * from the root controller interrupt pipe for port status change.
754 */
755 void
756 uhci_timo(addr)
757 void *addr;
758 {
759 usbd_xfer_handle xfer = addr;
760 usbd_pipe_handle pipe = xfer->pipe;
761 uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus;
762 int s;
763 u_char *p;
764
765 DPRINTFN(20, ("uhci_timo\n"));
766
767 usb_timeout(uhci_timo, xfer, sc->sc_ival, xfer->timo_handle);
768
769 p = KERNADDR(&xfer->dmabuf);
770 p[0] = 0;
771 if (UREAD2(sc, UHCI_PORTSC1) & (UHCI_PORTSC_CSC|UHCI_PORTSC_OCIC))
772 p[0] |= 1<<1;
773 if (UREAD2(sc, UHCI_PORTSC2) & (UHCI_PORTSC_CSC|UHCI_PORTSC_OCIC))
774 p[0] |= 1<<2;
775 if (p[0] == 0)
776 /* No change, try again in a while */
777 return;
778
779 xfer->actlen = 1;
780 xfer->status = USBD_NORMAL_COMPLETION;
781 s = splusb();
782 xfer->hcpriv = 0;
783 xfer->device->bus->intr_context++;
784 usb_transfer_complete(xfer);
785 xfer->device->bus->intr_context--;
786 splx(s);
787 }
788
789 void
790 uhci_root_intr_done(xfer)
791 usbd_xfer_handle xfer;
792 {
793 }
794
795 void
796 uhci_root_ctrl_done(xfer)
797 usbd_xfer_handle xfer;
798 {
799 }
800
801 void
802 uhci_lock_frames(sc)
803 uhci_softc_t *sc;
804 {
805 int s = splusb();
806
807 while (sc->sc_vflock & UHCI_HAS_LOCK) {
808 sc->sc_vflock |= UHCI_WANT_LOCK;
809 tsleep(&sc->sc_vflock, PRIBIO, "uhcqhl", 0);
810 }
811 sc->sc_vflock = UHCI_HAS_LOCK;
812 splx(s);
813 }
814
815 void
816 uhci_unlock_frames(sc)
817 uhci_softc_t *sc;
818 {
819 int s = splusb();
820
821 sc->sc_vflock &= ~UHCI_HAS_LOCK;
822 if (sc->sc_vflock & UHCI_WANT_LOCK)
823 wakeup(&sc->sc_vflock);
824 splx(s);
825 }
826
827 /*
828 * Allocate an interrupt information struct. A free list is kept
829 * for fast allocation.
830 */
831 uhci_intr_info_t *
832 uhci_alloc_intr_info(sc)
833 uhci_softc_t *sc;
834 {
835 uhci_intr_info_t *ii;
836
837 ii = LIST_FIRST(&uhci_ii_free);
838 if (ii)
839 LIST_REMOVE(ii, list);
840 else {
841 ii = malloc(sizeof(uhci_intr_info_t), M_USBHC, M_NOWAIT);
842 }
843 ii->sc = sc;
844 #if defined(__FreeBSD__)
845 callout_handle_init(&ii->timeout_handle);
846 #endif
847
848 return ii;
849 }
850
851 void
852 uhci_free_intr_info(ii)
853 uhci_intr_info_t *ii;
854 {
855 LIST_INSERT_HEAD(&uhci_ii_free, ii, list); /* and put on free list */
856 }
857
858 /* Add control QH, called at splusb(). */
859 void
860 uhci_add_ctrl(sc, sqh)
861 uhci_softc_t *sc;
862 uhci_soft_qh_t *sqh;
863 {
864 uhci_soft_qh_t *eqh;
865
866 SPLUSBCHECK;
867
868 DPRINTFN(10, ("uhci_add_ctrl: sqh=%p\n", sqh));
869 eqh = sc->sc_ctl_end;
870 sqh->hlink = eqh->hlink;
871 sqh->qh.qh_hlink = eqh->qh.qh_hlink;
872 eqh->hlink = sqh;
873 eqh->qh.qh_hlink = LE(sqh->physaddr | UHCI_PTR_Q);
874 sc->sc_ctl_end = sqh;
875 }
876
877 /* Remove control QH, called at splusb(). */
878 void
879 uhci_remove_ctrl(sc, sqh)
880 uhci_softc_t *sc;
881 uhci_soft_qh_t *sqh;
882 {
883 uhci_soft_qh_t *pqh;
884
885 SPLUSBCHECK;
886
887 DPRINTFN(10, ("uhci_remove_ctrl: sqh=%p\n", sqh));
888 for (pqh = sc->sc_ctl_start; pqh->hlink != sqh; pqh=pqh->hlink)
889 #if defined(DIAGNOSTIC) || defined(UHCI_DEBUG)
890 if (LE(pqh->qh.qh_hlink) & UHCI_PTR_T) {
891 printf("uhci_remove_ctrl: QH not found\n");
892 return;
893 }
894 #else
895 ;
896 #endif
897 pqh->hlink = sqh->hlink;
898 pqh->qh.qh_hlink = sqh->qh.qh_hlink;
899 if (sc->sc_ctl_end == sqh)
900 sc->sc_ctl_end = pqh;
901 }
902
903 /* Add bulk QH, called at splusb(). */
904 void
905 uhci_add_bulk(sc, sqh)
906 uhci_softc_t *sc;
907 uhci_soft_qh_t *sqh;
908 {
909 uhci_soft_qh_t *eqh;
910
911 SPLUSBCHECK;
912
913 DPRINTFN(10, ("uhci_add_bulk: sqh=%p\n", sqh));
914 eqh = sc->sc_bulk_end;
915 sqh->hlink = eqh->hlink;
916 sqh->qh.qh_hlink = eqh->qh.qh_hlink;
917 eqh->hlink = sqh;
918 eqh->qh.qh_hlink = LE(sqh->physaddr | UHCI_PTR_Q);
919 sc->sc_bulk_end = sqh;
920 }
921
922 /* Remove bulk QH, called at splusb(). */
923 void
924 uhci_remove_bulk(sc, sqh)
925 uhci_softc_t *sc;
926 uhci_soft_qh_t *sqh;
927 {
928 uhci_soft_qh_t *pqh;
929
930 SPLUSBCHECK;
931
932 DPRINTFN(10, ("uhci_remove_bulk: sqh=%p\n", sqh));
933 for (pqh = sc->sc_bulk_start; pqh->hlink != sqh; pqh = pqh->hlink)
934 #if defined(DIAGNOSTIC) || defined(UHCI_DEBUG)
935 if (LE(pqh->qh.qh_hlink) & UHCI_PTR_T) {
936 printf("uhci_remove_bulk: QH not found\n");
937 return;
938 }
939 #else
940 ;
941 #endif
942 pqh->hlink = sqh->hlink;
943 pqh->qh.qh_hlink = sqh->qh.qh_hlink;
944 if (sc->sc_bulk_end == sqh)
945 sc->sc_bulk_end = pqh;
946 }
947
948 int
949 uhci_intr(arg)
950 void *arg;
951 {
952 uhci_softc_t *sc = arg;
953 int status;
954 int ack;
955
956 #ifdef UHCI_DEBUG
957 if (uhcidebug > 15) {
958 DPRINTF(("%s: uhci_intr\n", USBDEVNAME(sc->sc_bus.bdev)));
959 uhci_dumpregs(sc);
960 }
961 #endif
962
963 status = UREAD2(sc, UHCI_STS);
964 if (status == 0) /* The interrupt was not for us. */
965 return (0);
966
967 #if defined(DIAGNOSTIC) && defined(__NetBSD__)
968 if (sc->sc_suspend != PWR_RESUME)
969 printf("uhci_intr: suspended sts=0x%x\n", status);
970 #endif
971
972 ack = 0;
973 if (status & UHCI_STS_USBINT)
974 ack |= UHCI_STS_USBINT;
975 if (status & UHCI_STS_USBEI)
976 ack |= UHCI_STS_USBEI;
977 if (status & UHCI_STS_RD) {
978 ack |= UHCI_STS_RD;
979 printf("%s: resume detect\n", USBDEVNAME(sc->sc_bus.bdev));
980 }
981 if (status & UHCI_STS_HSE) {
982 ack |= UHCI_STS_HSE;
983 printf("%s: host system error\n", USBDEVNAME(sc->sc_bus.bdev));
984 }
985 if (status & UHCI_STS_HCPE) {
986 ack |= UHCI_STS_HCPE;
987 printf("%s: host controller process error\n",
988 USBDEVNAME(sc->sc_bus.bdev));
989 }
990 if (status & UHCI_STS_HCH) {
991 /* no acknowledge needed */
992 printf("%s: host controller halted\n",
993 USBDEVNAME(sc->sc_bus.bdev));
994 sc->sc_dying = 1;
995 }
996
997 if (ack) /* acknowledge the ints */
998 UWRITE2(sc, UHCI_STS, ack);
999 else /* nothing to acknowledge */
1000 return (0);
1001
1002 sc->sc_bus.no_intrs++;
1003 usb_schedsoftintr(&sc->sc_bus);
1004
1005 DPRINTFN(10, ("%s: uhci_intr: exit\n", USBDEVNAME(sc->sc_bus.bdev)));
1006
1007 return (1);
1008 }
1009
1010 void
1011 uhci_softintr(bus)
1012 struct usbd_bus *bus;
1013 {
1014 uhci_softc_t *sc = (uhci_softc_t *)bus;
1015 uhci_intr_info_t *ii;
1016
1017 DPRINTFN(10,("%s: uhci_softintr\n", USBDEVNAME(sc->sc_bus.bdev)));
1018
1019 sc->sc_bus.intr_context++;
1020
1021 /*
1022 * Interrupts on UHCI really suck. When the host controller
1023 * interrupts because a transfer is completed there is no
1024 * way of knowing which transfer it was. You can scan down
1025 * the TDs and QHs of the previous frame to limit the search,
1026 * but that assumes that the interrupt was not delayed by more
1027 * than 1 ms, which may not always be true (e.g. after debug
1028 * output on a slow console).
1029 * We scan all interrupt descriptors to see if any have
1030 * completed.
1031 */
1032 for (ii = LIST_FIRST(&sc->sc_intrhead); ii; ii = LIST_NEXT(ii, list))
1033 uhci_check_intr(sc, ii);
1034
1035 sc->sc_bus.intr_context--;
1036 }
1037
1038 /* Check for an interrupt. */
1039 void
1040 uhci_check_intr(sc, ii)
1041 uhci_softc_t *sc;
1042 uhci_intr_info_t *ii;
1043 {
1044 uhci_soft_td_t *std, *lstd;
1045 u_int32_t status;
1046
1047 DPRINTFN(15, ("uhci_check_intr: ii=%p\n", ii));
1048 #ifdef DIAGNOSTIC
1049 if (ii == NULL) {
1050 printf("uhci_check_intr: no ii? %p\n", ii);
1051 return;
1052 }
1053 #endif
1054 if (ii->stdstart == NULL)
1055 return;
1056 lstd = ii->stdend;
1057 #ifdef DIAGNOSTIC
1058 if (lstd == NULL) {
1059 printf("uhci_check_intr: std==0\n");
1060 return;
1061 }
1062 #endif
1063 /*
1064 * If the last TD is still active we need to check whether there
1065 * is a an error somewhere in the middle, or whether there was a
1066 * short packet (SPD and not ACTIVE).
1067 */
1068 if (LE(lstd->td.td_status) & UHCI_TD_ACTIVE) {
1069 DPRINTFN(15, ("uhci_check_intr: active ii=%p\n", ii));
1070 for (std = ii->stdstart; std != lstd; std = std->link.std) {
1071 status = LE(std->td.td_status);
1072 /* If there's an active TD the xfer isn't done. */
1073 if (status & UHCI_TD_ACTIVE)
1074 break;
1075 /* Any kind of error makes the xfer done. */
1076 if (status & UHCI_TD_STALLED)
1077 goto done;
1078 /* We want short packets, and it is short: it's done */
1079 if ((status & UHCI_TD_SPD) &&
1080 UHCI_TD_GET_ACTLEN(status) <
1081 UHCI_TD_GET_MAXLEN(LE(std->td.td_token)))
1082 goto done;
1083 }
1084 DPRINTFN(15, ("uhci_check_intr: ii=%p std=%p still active\n",
1085 ii, ii->stdstart));
1086 return;
1087 }
1088 done:
1089 DPRINTFN(15, ("uhci_check_intr: ii=%p done\n", ii));
1090 usb_untimeout(uhci_timeout, ii, ii->timeout_handle);
1091 uhci_idone(ii);
1092 }
1093
1094 /* Called at splusb() */
1095 void
1096 uhci_idone(ii)
1097 uhci_intr_info_t *ii;
1098 {
1099 usbd_xfer_handle xfer = ii->xfer;
1100 struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
1101 uhci_soft_td_t *std;
1102 u_int32_t status = 0, nstatus;
1103 int actlen;
1104
1105 #ifdef DIAGNOSTIC
1106 {
1107 int s = splhigh();
1108 if (ii->isdone) {
1109 splx(s);
1110 printf("uhci_idone: ii=%p is done!\n", ii);
1111 return;
1112 }
1113 ii->isdone = 1;
1114 splx(s);
1115 }
1116 #endif
1117
1118 if (xfer->status == USBD_CANCELLED ||
1119 xfer->status == USBD_TIMEOUT) {
1120 DPRINTF(("uhci_idone: aborted xfer=%p\n", xfer));
1121 return;
1122 }
1123
1124 if (xfer->nframes != 0) {
1125 /* Isoc transfer, do things differently. */
1126 uhci_soft_td_t **stds = upipe->u.iso.stds;
1127 int i, n, nframes;
1128
1129 DPRINTFN(5,("uhci_idone: ii=%p isoc ready\n", ii));
1130
1131 nframes = xfer->nframes;
1132 actlen = 0;
1133 n = xfer->hcprivint;
1134 for (i = 0; i < nframes; i++) {
1135 std = stds[n];
1136 #ifdef UHCI_DEBUG
1137 if (uhcidebug > 5) {
1138 DPRINTFN(-1,("uhci_idone: isoc TD %d\n", i));
1139 uhci_dump_td(std);
1140 }
1141 #endif
1142 if (++n >= UHCI_VFRAMELIST_COUNT)
1143 n = 0;
1144 status = LE(std->td.td_status);
1145 actlen += UHCI_TD_GET_ACTLEN(status);
1146 }
1147 upipe->u.iso.inuse -= nframes;
1148 xfer->actlen = actlen;
1149 xfer->status = USBD_NORMAL_COMPLETION;
1150 xfer->hcpriv = ii;
1151 usb_transfer_complete(xfer);
1152 return;
1153 }
1154
1155 #ifdef UHCI_DEBUG
1156 DPRINTFN(10, ("uhci_idone: ii=%p, xfer=%p, pipe=%p ready\n",
1157 ii, xfer, upipe));
1158 if (uhcidebug > 10)
1159 uhci_dump_tds(ii->stdstart);
1160 #endif
1161
1162 /* The transfer is done, compute actual length and status. */
1163 actlen = 0;
1164 for (std = ii->stdstart; std != NULL; std = std->link.std) {
1165 nstatus = LE(std->td.td_status);
1166 if (nstatus & UHCI_TD_ACTIVE)
1167 break;
1168
1169 status = nstatus;
1170 if (UHCI_TD_GET_PID(LE(std->td.td_token)) != UHCI_TD_PID_SETUP)
1171 actlen += UHCI_TD_GET_ACTLEN(status);
1172 }
1173 /* If there are left over TDs we need to update the toggle. */
1174 if (std != NULL)
1175 upipe->nexttoggle = UHCI_TD_GET_DT(LE(std->td.td_token));
1176
1177 status &= UHCI_TD_ERROR;
1178 DPRINTFN(10, ("uhci_check_intr: actlen=%d, status=0x%x\n",
1179 actlen, status));
1180 xfer->actlen = actlen;
1181 if (status != 0) {
1182 DPRINTFN((status == UHCI_TD_STALLED)*10,
1183 ("uhci_idone: error, addr=%d, endpt=0x%02x, "
1184 "status 0x%b\n",
1185 xfer->pipe->device->address,
1186 xfer->pipe->endpoint->edesc->bEndpointAddress,
1187 (int)status,
1188 "\20\22BITSTUFF\23CRCTO\24NAK\25BABBLE\26DBUFFER\27"
1189 "STALLED\30ACTIVE"));
1190 if (status == UHCI_TD_STALLED)
1191 xfer->status = USBD_STALLED;
1192 else
1193 xfer->status = USBD_IOERROR; /* more info XXX */
1194 } else {
1195 xfer->status = USBD_NORMAL_COMPLETION;
1196 }
1197 xfer->hcpriv = ii;
1198 usb_transfer_complete(xfer);
1199 }
1200
1201 /*
1202 * Called when a request does not complete.
1203 */
1204 void
1205 uhci_timeout(addr)
1206 void *addr;
1207 {
1208 uhci_intr_info_t *ii = addr;
1209
1210 DPRINTF(("uhci_timeout: ii=%p\n", ii));
1211
1212 #ifdef UHCI_DEBUG
1213 if (uhcidebug > 10)
1214 uhci_dump_tds(ii->stdstart);
1215 #endif
1216
1217 ii->xfer->device->bus->intr_context++;
1218 uhci_abort_xfer(ii->xfer, USBD_TIMEOUT);
1219 ii->xfer->device->bus->intr_context--;
1220 }
1221
1222 /*
1223 * Wait here until controller claims to have an interrupt.
1224 * Then call uhci_intr and return. Use timeout to avoid waiting
1225 * too long.
1226 * Only used during boot when interrupts are not enabled yet.
1227 */
1228 void
1229 uhci_waitintr(sc, xfer)
1230 uhci_softc_t *sc;
1231 usbd_xfer_handle xfer;
1232 {
1233 int timo = xfer->timeout;
1234 uhci_intr_info_t *ii;
1235
1236 DPRINTFN(10,("uhci_waitintr: timeout = %dms\n", timo));
1237
1238 xfer->status = USBD_IN_PROGRESS;
1239 for (; timo >= 0; timo--) {
1240 usb_delay_ms(&sc->sc_bus, 1);
1241 DPRINTFN(20,("uhci_waitintr: 0x%04x\n", UREAD2(sc, UHCI_STS)));
1242 if (UREAD2(sc, UHCI_STS) & UHCI_STS_USBINT) {
1243 uhci_intr(sc);
1244 if (xfer->status != USBD_IN_PROGRESS)
1245 return;
1246 }
1247 }
1248
1249 /* Timeout */
1250 DPRINTF(("uhci_waitintr: timeout\n"));
1251 for (ii = LIST_FIRST(&sc->sc_intrhead);
1252 ii != NULL && ii->xfer != xfer;
1253 ii = LIST_NEXT(ii, list))
1254 ;
1255 #ifdef DIAGNOSTIC
1256 if (ii == NULL)
1257 panic("uhci_waitintr: lost intr_info\n");
1258 #endif
1259 uhci_idone(ii);
1260 }
1261
1262 void
1263 uhci_poll(bus)
1264 struct usbd_bus *bus;
1265 {
1266 uhci_softc_t *sc = (uhci_softc_t *)bus;
1267
1268 if (UREAD2(sc, UHCI_STS) & UHCI_STS_USBINT)
1269 uhci_intr(sc);
1270 }
1271
1272 #if 0
1273 void
1274 uhci_reset(p)
1275 void *p;
1276 {
1277 uhci_softc_t *sc = p;
1278 int n;
1279
1280 UHCICMD(sc, UHCI_CMD_HCRESET);
1281 /* The reset bit goes low when the controller is done. */
1282 for (n = 0; n < UHCI_RESET_TIMEOUT &&
1283 (UREAD2(sc, UHCI_CMD) & UHCI_CMD_HCRESET); n++)
1284 delay(100);
1285 if (n >= UHCI_RESET_TIMEOUT)
1286 printf("%s: controller did not reset\n",
1287 USBDEVNAME(sc->sc_bus.bdev));
1288 }
1289 #endif
1290
1291 usbd_status
1292 uhci_run(sc, run)
1293 uhci_softc_t *sc;
1294 int run;
1295 {
1296 int s, n, running;
1297 u_int16_t cmd;
1298
1299 run = run != 0;
1300 s = splusb();
1301 DPRINTF(("uhci_run: setting run=%d\n", run));
1302 cmd = UREAD2(sc, UHCI_CMD);
1303 if (run)
1304 cmd |= UHCI_CMD_RS;
1305 else
1306 cmd &= ~UHCI_CMD_RS;
1307 UHCICMD(sc, cmd);
1308 for(n = 0; n < 10; n++) {
1309 running = !(UREAD2(sc, UHCI_STS) & UHCI_STS_HCH);
1310 /* return when we've entered the state we want */
1311 if (run == running) {
1312 splx(s);
1313 DPRINTF(("uhci_run: done cmd=0x%x sts=0x%x\n",
1314 UREAD2(sc, UHCI_CMD), UREAD2(sc, UHCI_STS)));
1315 return (USBD_NORMAL_COMPLETION);
1316 }
1317 usb_delay_ms(&sc->sc_bus, 1);
1318 }
1319 splx(s);
1320 printf("%s: cannot %s\n", USBDEVNAME(sc->sc_bus.bdev),
1321 run ? "start" : "stop");
1322 return (USBD_IOERROR);
1323 }
1324
1325 /*
1326 * Memory management routines.
1327 * uhci_alloc_std allocates TDs
1328 * uhci_alloc_sqh allocates QHs
1329 * These two routines do their own free list management,
1330 * partly for speed, partly because allocating DMAable memory
1331 * has page size granularaity so much memory would be wasted if
1332 * only one TD/QH (32 bytes) was placed in each allocated chunk.
1333 */
1334
1335 uhci_soft_td_t *
1336 uhci_alloc_std(sc)
1337 uhci_softc_t *sc;
1338 {
1339 uhci_soft_td_t *std;
1340 usbd_status err;
1341 int i, offs;
1342 usb_dma_t dma;
1343
1344 if (sc->sc_freetds == NULL) {
1345 DPRINTFN(2,("uhci_alloc_std: allocating chunk\n"));
1346 err = usb_allocmem(&sc->sc_bus, UHCI_STD_SIZE * UHCI_STD_CHUNK,
1347 UHCI_TD_ALIGN, &dma);
1348 if (err)
1349 return (0);
1350 for(i = 0; i < UHCI_STD_CHUNK; i++) {
1351 offs = i * UHCI_STD_SIZE;
1352 std = (uhci_soft_td_t *)((char *)KERNADDR(&dma) +offs);
1353 std->physaddr = DMAADDR(&dma) + offs;
1354 std->link.std = sc->sc_freetds;
1355 sc->sc_freetds = std;
1356 }
1357 }
1358 std = sc->sc_freetds;
1359 sc->sc_freetds = std->link.std;
1360 memset(&std->td, 0, sizeof(uhci_td_t));
1361 return std;
1362 }
1363
1364 void
1365 uhci_free_std(sc, std)
1366 uhci_softc_t *sc;
1367 uhci_soft_td_t *std;
1368 {
1369 #ifdef DIAGNOSTIC
1370 #define TD_IS_FREE 0x12345678
1371 if (std->td.td_token == LE(TD_IS_FREE)) {
1372 printf("uhci_free_std: freeing free TD %p\n", std);
1373 return;
1374 }
1375 std->td.td_token = LE(TD_IS_FREE);
1376 #endif
1377 std->link.std = sc->sc_freetds;
1378 sc->sc_freetds = std;
1379 }
1380
1381 uhci_soft_qh_t *
1382 uhci_alloc_sqh(sc)
1383 uhci_softc_t *sc;
1384 {
1385 uhci_soft_qh_t *sqh;
1386 usbd_status err;
1387 int i, offs;
1388 usb_dma_t dma;
1389
1390 if (sc->sc_freeqhs == NULL) {
1391 DPRINTFN(2, ("uhci_alloc_sqh: allocating chunk\n"));
1392 err = usb_allocmem(&sc->sc_bus, UHCI_SQH_SIZE * UHCI_SQH_CHUNK,
1393 UHCI_QH_ALIGN, &dma);
1394 if (err)
1395 return (0);
1396 for(i = 0; i < UHCI_SQH_CHUNK; i++) {
1397 offs = i * UHCI_SQH_SIZE;
1398 sqh = (uhci_soft_qh_t *)((char *)KERNADDR(&dma) +offs);
1399 sqh->physaddr = DMAADDR(&dma) + offs;
1400 sqh->hlink = sc->sc_freeqhs;
1401 sc->sc_freeqhs = sqh;
1402 }
1403 }
1404 sqh = sc->sc_freeqhs;
1405 sc->sc_freeqhs = sqh->hlink;
1406 memset(&sqh->qh, 0, sizeof(uhci_qh_t));
1407 return (sqh);
1408 }
1409
1410 void
1411 uhci_free_sqh(sc, sqh)
1412 uhci_softc_t *sc;
1413 uhci_soft_qh_t *sqh;
1414 {
1415 sqh->hlink = sc->sc_freeqhs;
1416 sc->sc_freeqhs = sqh;
1417 }
1418
1419 #if 0
1420 /*
1421 * Enter a list of transfers onto a control queue.
1422 * Called at splusb()
1423 */
1424 void
1425 uhci_enter_ctl_q(sc, sqh, ii)
1426 uhci_softc_t *sc;
1427 uhci_soft_qh_t *sqh;
1428 uhci_intr_info_t *ii;
1429 {
1430 DPRINTFN(5, ("uhci_enter_ctl_q: sqh=%p\n", sqh));
1431
1432 }
1433 #endif
1434
1435 void
1436 uhci_free_std_chain(sc, std, stdend)
1437 uhci_softc_t *sc;
1438 uhci_soft_td_t *std;
1439 uhci_soft_td_t *stdend;
1440 {
1441 uhci_soft_td_t *p;
1442
1443 for (; std != stdend; std = p) {
1444 p = std->link.std;
1445 uhci_free_std(sc, std);
1446 }
1447 }
1448
1449 usbd_status
1450 uhci_alloc_std_chain(upipe, sc, len, rd, flags, dma, sp, ep)
1451 struct uhci_pipe *upipe;
1452 uhci_softc_t *sc;
1453 int len, rd;
1454 u_int16_t flags;
1455 usb_dma_t *dma;
1456 uhci_soft_td_t **sp, **ep;
1457 {
1458 uhci_soft_td_t *p, *lastp;
1459 uhci_physaddr_t lastlink;
1460 int i, ntd, l, tog, maxp;
1461 u_int32_t status;
1462 int addr = upipe->pipe.device->address;
1463 int endpt = upipe->pipe.endpoint->edesc->bEndpointAddress;
1464
1465 DPRINTFN(8, ("uhci_alloc_std_chain: addr=%d endpt=%d len=%d ls=%d "
1466 "flags=0x%x\n", addr, UE_GET_ADDR(endpt), len,
1467 upipe->pipe.device->lowspeed, flags));
1468 maxp = UGETW(upipe->pipe.endpoint->edesc->wMaxPacketSize);
1469 if (maxp == 0) {
1470 printf("uhci_alloc_std_chain: maxp=0\n");
1471 return (USBD_INVAL);
1472 }
1473 ntd = (len + maxp - 1) / maxp;
1474 if ((flags & USBD_FORCE_SHORT_XFER) && len % maxp == 0)
1475 ntd++;
1476 DPRINTFN(10, ("uhci_alloc_std_chain: maxp=%d ntd=%d\n", maxp, ntd));
1477 if (ntd == 0) {
1478 *sp = *ep = 0;
1479 DPRINTFN(-1,("uhci_alloc_std_chain: ntd=0\n"));
1480 return (USBD_NORMAL_COMPLETION);
1481 }
1482 tog = upipe->nexttoggle;
1483 if (ntd % 2 == 0)
1484 tog ^= 1;
1485 upipe->nexttoggle = tog ^ 1;
1486 lastp = 0;
1487 lastlink = UHCI_PTR_T;
1488 ntd--;
1489 status = UHCI_TD_ZERO_ACTLEN(UHCI_TD_SET_ERRCNT(3) | UHCI_TD_ACTIVE);
1490 if (upipe->pipe.device->lowspeed)
1491 status |= UHCI_TD_LS;
1492 if (flags & USBD_SHORT_XFER_OK)
1493 status |= UHCI_TD_SPD;
1494 for (i = ntd; i >= 0; i--) {
1495 p = uhci_alloc_std(sc);
1496 if (p == NULL) {
1497 uhci_free_std_chain(sc, lastp, 0);
1498 return (USBD_NOMEM);
1499 }
1500 p->link.std = lastp;
1501 if (lastlink == UHCI_PTR_T)
1502 p->td.td_link = LE(lastlink);
1503 else
1504 p->td.td_link = LE(lastlink|UHCI_PTR_VF);
1505 lastp = p;
1506 lastlink = p->physaddr;
1507 p->td.td_status = LE(status);
1508 if (i == ntd) {
1509 /* last TD */
1510 l = len % maxp;
1511 if (l == 0 && !(flags & USBD_FORCE_SHORT_XFER))
1512 l = maxp;
1513 *ep = p;
1514 } else
1515 l = maxp;
1516 p->td.td_token =
1517 LE(rd ? UHCI_TD_IN (l, endpt, addr, tog) :
1518 UHCI_TD_OUT(l, endpt, addr, tog));
1519 p->td.td_buffer = LE(DMAADDR(dma) + i * maxp);
1520 tog ^= 1;
1521 }
1522 *sp = lastp;
1523 DPRINTFN(10, ("uhci_alloc_std_chain: nexttog=%d\n",
1524 upipe->nexttoggle));
1525 return (USBD_NORMAL_COMPLETION);
1526 }
1527
1528 void
1529 uhci_device_clear_toggle(pipe)
1530 usbd_pipe_handle pipe;
1531 {
1532 struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
1533 upipe->nexttoggle = 0;
1534 }
1535
1536 void
1537 uhci_noop(pipe)
1538 usbd_pipe_handle pipe;
1539 {
1540 }
1541
1542 usbd_status
1543 uhci_device_bulk_transfer(xfer)
1544 usbd_xfer_handle xfer;
1545 {
1546 usbd_status err;
1547
1548 /* Insert last in queue. */
1549 err = usb_insert_transfer(xfer);
1550 if (err)
1551 return (err);
1552
1553 /* Pipe isn't running (otherwise err would be USBD_INPROG),
1554 * start first
1555 */
1556 return (uhci_device_bulk_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
1557 }
1558
1559 usbd_status
1560 uhci_device_bulk_start(xfer)
1561 usbd_xfer_handle xfer;
1562 {
1563 struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
1564 usbd_device_handle dev = upipe->pipe.device;
1565 uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
1566 uhci_intr_info_t *ii = upipe->iinfo;
1567 uhci_soft_td_t *data, *dataend;
1568 uhci_soft_qh_t *sqh;
1569 usbd_status err;
1570 int len, isread, endpt;
1571 int s;
1572
1573 DPRINTFN(3, ("uhci_device_bulk_transfer: xfer=%p len=%d flags=%d\n",
1574 xfer, xfer->length, xfer->flags));
1575
1576 if (sc->sc_dying)
1577 return (USBD_IOERROR);
1578
1579 #ifdef DIAGNOSTIC
1580 if (xfer->rqflags & URQ_REQUEST)
1581 panic("uhci_device_bulk_transfer: a request\n");
1582 #endif
1583
1584 len = xfer->length;
1585 endpt = xfer->pipe->endpoint->edesc->bEndpointAddress;
1586 isread = UE_GET_DIR(endpt) == UE_DIR_IN;
1587 sqh = upipe->u.bulk.sqh;
1588
1589 upipe->u.bulk.isread = isread;
1590 upipe->u.bulk.length = len;
1591
1592 err = uhci_alloc_std_chain(upipe, sc, len, isread, xfer->flags,
1593 &xfer->dmabuf, &data, &dataend);
1594 if (err)
1595 return (err);
1596 dataend->td.td_status |= LE(UHCI_TD_IOC);
1597
1598 #ifdef UHCI_DEBUG
1599 if (uhcidebug > 8) {
1600 DPRINTF(("uhci_device_bulk_transfer: data(1)\n"));
1601 uhci_dump_tds(data);
1602 }
1603 #endif
1604
1605 /* Set up interrupt info. */
1606 ii->xfer = xfer;
1607 ii->stdstart = data;
1608 ii->stdend = dataend;
1609 #if defined(__FreeBSD__)
1610 callout_handle_init(&ii->timeout_handle);
1611 #endif
1612 #ifdef DIAGNOSTIC
1613 if (!ii->isdone) {
1614 printf("uhci_device_bulk_transfer: not done, ii=%p\n", ii);
1615 }
1616 ii->isdone = 0;
1617 #endif
1618
1619 sqh->elink = data;
1620 sqh->qh.qh_elink = LE(data->physaddr);
1621 sqh->intr_info = ii;
1622
1623 s = splusb();
1624 uhci_add_bulk(sc, sqh);
1625 LIST_INSERT_HEAD(&sc->sc_intrhead, ii, list);
1626
1627 if (xfer->timeout && !sc->sc_bus.use_polling) {
1628 usb_timeout(uhci_timeout, ii, MS_TO_TICKS(xfer->timeout),
1629 ii->timeout_handle);
1630 }
1631 splx(s);
1632
1633 #ifdef UHCI_DEBUG
1634 if (uhcidebug > 10) {
1635 DPRINTF(("uhci_device_bulk_transfer: data(2)\n"));
1636 uhci_dump_tds(data);
1637 }
1638 #endif
1639
1640 if (sc->sc_bus.use_polling)
1641 uhci_waitintr(sc, xfer);
1642
1643 return (USBD_IN_PROGRESS);
1644 }
1645
1646 /* Abort a device bulk request. */
1647 void
1648 uhci_device_bulk_abort(xfer)
1649 usbd_xfer_handle xfer;
1650 {
1651 DPRINTF(("uhci_device_bulk_abort:\n"));
1652 uhci_abort_xfer(xfer, USBD_CANCELLED);
1653 }
1654
1655 void
1656 uhci_abort_xfer(xfer, status)
1657 usbd_xfer_handle xfer;
1658 usbd_status status;
1659 {
1660 struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
1661 uhci_intr_info_t *ii = upipe->iinfo;
1662 uhci_soft_td_t *std;
1663
1664 DPRINTFN(1,("uhci_abort_xfer: xfer=%p, status=%d\n", xfer, status));
1665
1666 /* Make interrupt routine ignore it, */
1667 xfer->status = status;
1668
1669 /* don't timeout, */
1670 usb_untimeout(uhci_timeout, ii, ii->timeout_handle);
1671
1672 /* make hardware ignore it, */
1673 for (std = ii->stdstart; std != 0; std = std->link.std)
1674 std->td.td_status &= LE(~(UHCI_TD_ACTIVE | UHCI_TD_IOC));
1675
1676 xfer->hcpriv = ii;
1677
1678 #if 1
1679 /* Make sure hardware has completed. */
1680 if (xfer->device->bus->intr_context) {
1681 /* We have no process context, so we can't use tsleep(). */
1682 timeout(uhci_abort_xfer_end, xfer, hz / USB_FRAMES_PER_SECOND);
1683 } else {
1684 #if defined(DIAGNOSTIC) && defined(__i386__) && defined(__FreeBSD__)
1685 KASSERT(intr_nesting_level == 0,
1686 ("ohci_abort_req in interrupt context"));
1687 #endif
1688 usb_delay_ms(xfer->pipe->device->bus, 1);
1689 /* and call final part of interrupt handler. */
1690 uhci_abort_xfer_end(xfer);
1691 }
1692 #else
1693 delay(1000);
1694 uhci_abort_xfer_end(xfer);
1695 #endif
1696 }
1697
1698 void
1699 uhci_abort_xfer_end(v)
1700 void *v;
1701 {
1702 usbd_xfer_handle xfer = v;
1703 int s;
1704
1705 s = splusb();
1706 usb_transfer_complete(xfer);
1707 splx(s);
1708 }
1709
1710 /* Close a device bulk pipe. */
1711 void
1712 uhci_device_bulk_close(pipe)
1713 usbd_pipe_handle pipe;
1714 {
1715 struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
1716 usbd_device_handle dev = upipe->pipe.device;
1717 uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
1718
1719 uhci_free_sqh(sc, upipe->u.bulk.sqh);
1720 uhci_free_intr_info(upipe->iinfo);
1721 /* XXX free other resources */
1722 }
1723
1724 usbd_status
1725 uhci_device_ctrl_transfer(xfer)
1726 usbd_xfer_handle xfer;
1727 {
1728 usbd_status err;
1729
1730 /* Insert last in queue. */
1731 err = usb_insert_transfer(xfer);
1732 if (err)
1733 return (err);
1734
1735 /* Pipe isn't running (otherwise err would be USBD_INPROG),
1736 * start first
1737 */
1738 return (uhci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
1739 }
1740
1741 usbd_status
1742 uhci_device_ctrl_start(xfer)
1743 usbd_xfer_handle xfer;
1744 {
1745 uhci_softc_t *sc = (uhci_softc_t *)xfer->pipe->device->bus;
1746 usbd_status err;
1747
1748 if (sc->sc_dying)
1749 return (USBD_IOERROR);
1750
1751 #ifdef DIAGNOSTIC
1752 if (!(xfer->rqflags & URQ_REQUEST))
1753 panic("uhci_device_ctrl_transfer: not a request\n");
1754 #endif
1755
1756 err = uhci_device_request(xfer);
1757 if (err)
1758 return (err);
1759
1760 if (sc->sc_bus.use_polling)
1761 uhci_waitintr(sc, xfer);
1762 return (USBD_IN_PROGRESS);
1763 }
1764
1765 usbd_status
1766 uhci_device_intr_transfer(xfer)
1767 usbd_xfer_handle xfer;
1768 {
1769 usbd_status err;
1770
1771 /* Insert last in queue. */
1772 err = usb_insert_transfer(xfer);
1773 if (err)
1774 return (err);
1775
1776 /* Pipe isn't running (otherwise err would be USBD_INPROG),
1777 * start first
1778 */
1779 return (uhci_device_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
1780 }
1781
1782 usbd_status
1783 uhci_device_intr_start(xfer)
1784 usbd_xfer_handle xfer;
1785 {
1786 struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
1787 usbd_device_handle dev = upipe->pipe.device;
1788 uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
1789 uhci_intr_info_t *ii = upipe->iinfo;
1790 uhci_soft_td_t *data, *dataend;
1791 uhci_soft_qh_t *sqh;
1792 usbd_status err;
1793 int i, s;
1794
1795 if (sc->sc_dying)
1796 return (USBD_IOERROR);
1797
1798 DPRINTFN(3,("uhci_device_intr_transfer: xfer=%p len=%d flags=%d\n",
1799 xfer, xfer->length, xfer->flags));
1800
1801 #ifdef DIAGNOSTIC
1802 if (xfer->rqflags & URQ_REQUEST)
1803 panic("uhci_device_intr_transfer: a request\n");
1804 #endif
1805
1806 err = uhci_alloc_std_chain(upipe, sc, xfer->length, 1, xfer->flags,
1807 &xfer->dmabuf, &data, &dataend);
1808 if (err)
1809 return (err);
1810 dataend->td.td_status |= LE(UHCI_TD_IOC);
1811
1812 #ifdef UHCI_DEBUG
1813 if (uhcidebug > 10) {
1814 DPRINTF(("uhci_device_intr_transfer: data(1)\n"));
1815 uhci_dump_tds(data);
1816 uhci_dump_qh(upipe->u.intr.qhs[0]);
1817 }
1818 #endif
1819
1820 s = splusb();
1821 /* Set up interrupt info. */
1822 ii->xfer = xfer;
1823 ii->stdstart = data;
1824 ii->stdend = dataend;
1825 #if defined(__FreeBSD__)
1826 callout_handle_init(&ii->timeout_handle);
1827 #endif
1828 #ifdef DIAGNOSTIC
1829 if (!ii->isdone) {
1830 printf("uhci_device_intr_transfer: not done, ii=%p\n", ii);
1831 }
1832 ii->isdone = 0;
1833 #endif
1834
1835 DPRINTFN(10,("uhci_device_intr_transfer: qhs[0]=%p\n",
1836 upipe->u.intr.qhs[0]));
1837 for (i = 0; i < upipe->u.intr.npoll; i++) {
1838 sqh = upipe->u.intr.qhs[i];
1839 sqh->elink = data;
1840 sqh->qh.qh_elink = LE(data->physaddr);
1841 }
1842 splx(s);
1843
1844 #ifdef UHCI_DEBUG
1845 if (uhcidebug > 10) {
1846 DPRINTF(("uhci_device_intr_transfer: data(2)\n"));
1847 uhci_dump_tds(data);
1848 uhci_dump_qh(upipe->u.intr.qhs[0]);
1849 }
1850 #endif
1851
1852 return (USBD_IN_PROGRESS);
1853 }
1854
1855 /* Abort a device control request. */
1856 void
1857 uhci_device_ctrl_abort(xfer)
1858 usbd_xfer_handle xfer;
1859 {
1860 DPRINTF(("uhci_device_ctrl_abort:\n"));
1861 uhci_abort_xfer(xfer, USBD_CANCELLED);
1862 }
1863
1864 /* Close a device control pipe. */
1865 void
1866 uhci_device_ctrl_close(pipe)
1867 usbd_pipe_handle pipe;
1868 {
1869 struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
1870
1871 uhci_free_intr_info(upipe->iinfo);
1872 /* XXX free other resources? */
1873 }
1874
1875 /* Abort a device interrupt request. */
1876 void
1877 uhci_device_intr_abort(xfer)
1878 usbd_xfer_handle xfer;
1879 {
1880 DPRINTFN(1,("uhci_device_intr_abort: xfer=%p\n", xfer));
1881 if (xfer->pipe->intrxfer == xfer) {
1882 DPRINTFN(1,("uhci_device_intr_abort: remove\n"));
1883 xfer->pipe->intrxfer = 0;
1884 }
1885 uhci_abort_xfer(xfer, USBD_CANCELLED);
1886 }
1887
1888 /* Close a device interrupt pipe. */
1889 void
1890 uhci_device_intr_close(pipe)
1891 usbd_pipe_handle pipe;
1892 {
1893 struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
1894 uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus;
1895 int i, s, npoll;
1896
1897 upipe->iinfo->stdstart = 0; /* inactive */
1898
1899 /* Unlink descriptors from controller data structures. */
1900 npoll = upipe->u.intr.npoll;
1901 uhci_lock_frames(sc);
1902 for (i = 0; i < npoll; i++)
1903 uhci_remove_intr(sc, upipe->u.intr.qhs[i]->pos,
1904 upipe->u.intr.qhs[i]);
1905 uhci_unlock_frames(sc);
1906
1907 /*
1908 * We now have to wait for any activity on the physical
1909 * descriptors to stop.
1910 */
1911 usb_delay_ms(&sc->sc_bus, 2);
1912
1913 for(i = 0; i < npoll; i++)
1914 uhci_free_sqh(sc, upipe->u.intr.qhs[i]);
1915 free(upipe->u.intr.qhs, M_USBHC);
1916
1917 s = splusb();
1918 LIST_REMOVE(upipe->iinfo, list); /* remove from active list */
1919 splx(s);
1920 uhci_free_intr_info(upipe->iinfo);
1921
1922 /* XXX free other resources */
1923 }
1924
1925 usbd_status
1926 uhci_device_request(xfer)
1927 usbd_xfer_handle xfer;
1928 {
1929 struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
1930 usb_device_request_t *req = &xfer->request;
1931 usbd_device_handle dev = upipe->pipe.device;
1932 uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
1933 int addr = dev->address;
1934 int endpt = upipe->pipe.endpoint->edesc->bEndpointAddress;
1935 uhci_intr_info_t *ii = upipe->iinfo;
1936 uhci_soft_td_t *setup, *data, *stat, *next, *dataend;
1937 uhci_soft_qh_t *sqh;
1938 int len;
1939 u_int32_t ls;
1940 usbd_status err;
1941 int isread;
1942 int s;
1943
1944 DPRINTFN(3,("uhci_device_control type=0x%02x, request=0x%02x, "
1945 "wValue=0x%04x, wIndex=0x%04x len=%d, addr=%d, endpt=%d\n",
1946 req->bmRequestType, req->bRequest, UGETW(req->wValue),
1947 UGETW(req->wIndex), UGETW(req->wLength),
1948 addr, endpt));
1949
1950 ls = dev->lowspeed ? UHCI_TD_LS : 0;
1951 isread = req->bmRequestType & UT_READ;
1952 len = UGETW(req->wLength);
1953
1954 setup = upipe->u.ctl.setup;
1955 stat = upipe->u.ctl.stat;
1956 sqh = upipe->u.ctl.sqh;
1957
1958 /* Set up data transaction */
1959 if (len != 0) {
1960 upipe->nexttoggle = 1;
1961 err = uhci_alloc_std_chain(upipe, sc, len, isread, xfer->flags,
1962 &xfer->dmabuf, &data, &dataend);
1963 if (err)
1964 return (err);
1965 next = data;
1966 dataend->link.std = stat;
1967 dataend->td.td_link = LE(stat->physaddr | UHCI_PTR_VF);
1968 } else {
1969 next = stat;
1970 }
1971 upipe->u.ctl.length = len;
1972
1973 memcpy(KERNADDR(&upipe->u.ctl.reqdma), req, sizeof *req);
1974
1975 setup->link.std = next;
1976 setup->td.td_link = LE(next->physaddr | UHCI_PTR_VF);
1977 setup->td.td_status = LE(UHCI_TD_SET_ERRCNT(3) | ls | UHCI_TD_ACTIVE);
1978 setup->td.td_token = LE(UHCI_TD_SETUP(sizeof *req, endpt, addr));
1979 setup->td.td_buffer = LE(DMAADDR(&upipe->u.ctl.reqdma));
1980
1981 stat->link.std = 0;
1982 stat->td.td_link = LE(UHCI_PTR_T);
1983 stat->td.td_status = LE(UHCI_TD_SET_ERRCNT(3) | ls |
1984 UHCI_TD_ACTIVE | UHCI_TD_IOC);
1985 stat->td.td_token =
1986 LE(isread ? UHCI_TD_OUT(0, endpt, addr, 1) :
1987 UHCI_TD_IN (0, endpt, addr, 1));
1988 stat->td.td_buffer = LE(0);
1989
1990 #ifdef UHCI_DEBUG
1991 if (uhcidebug > 10) {
1992 DPRINTF(("uhci_device_request: before transfer\n"));
1993 uhci_dump_tds(setup);
1994 }
1995 #endif
1996
1997 /* Set up interrupt info. */
1998 ii->xfer = xfer;
1999 ii->stdstart = setup;
2000 ii->stdend = stat;
2001 #if defined(__FreeBSD__)
2002 callout_handle_init(&ii->timeout_handle);
2003 #endif
2004 #ifdef DIAGNOSTIC
2005 if (!ii->isdone) {
2006 printf("uhci_device_request: not done, ii=%p\n", ii);
2007 }
2008 ii->isdone = 0;
2009 #endif
2010
2011 sqh->elink = setup;
2012 sqh->qh.qh_elink = LE(setup->physaddr);
2013 sqh->intr_info = ii;
2014
2015 s = splusb();
2016 uhci_add_ctrl(sc, sqh);
2017 LIST_INSERT_HEAD(&sc->sc_intrhead, ii, list);
2018 #ifdef UHCI_DEBUG
2019 if (uhcidebug > 12) {
2020 uhci_soft_td_t *std;
2021 uhci_soft_qh_t *xqh;
2022 uhci_soft_qh_t *sxqh;
2023 int maxqh = 0;
2024 uhci_physaddr_t link;
2025 DPRINTF(("uhci_enter_ctl_q: follow from [0]\n"));
2026 for (std = sc->sc_vframes[0].htd, link = 0;
2027 (link & UHCI_PTR_Q) == 0;
2028 std = std->link.std) {
2029 link = LE(std->td.td_link);
2030 uhci_dump_td(std);
2031 }
2032 sxqh = (uhci_soft_qh_t *)std;
2033 uhci_dump_qh(sxqh);
2034 for (xqh = sxqh;
2035 xqh != NULL;
2036 xqh = (maxqh++ == 5 || xqh->hlink==sxqh ||
2037 xqh->hlink==xqh ? NULL : xqh->hlink)) {
2038 uhci_dump_qh(xqh);
2039 }
2040 DPRINTF(("Enqueued QH:\n"));
2041 uhci_dump_qh(sqh);
2042 uhci_dump_tds(sqh->elink);
2043 }
2044 #endif
2045 if (xfer->timeout && !sc->sc_bus.use_polling) {
2046 usb_timeout(uhci_timeout, ii,
2047 MS_TO_TICKS(xfer->timeout), ii->timeout_handle);
2048 }
2049 splx(s);
2050
2051 return (USBD_NORMAL_COMPLETION);
2052 }
2053
2054 usbd_status
2055 uhci_device_isoc_transfer(xfer)
2056 usbd_xfer_handle xfer;
2057 {
2058 usbd_status err;
2059
2060 DPRINTFN(5,("uhci_device_isoc_transfer: xfer=%p\n", xfer));
2061
2062 /* Put it on our queue, */
2063 err = usb_insert_transfer(xfer);
2064
2065 /* bail out on error, */
2066 if (err && err != USBD_IN_PROGRESS)
2067 return (err);
2068
2069 /* XXX should check inuse here */
2070
2071 /* insert into schedule, */
2072 uhci_device_isoc_enter(xfer);
2073
2074 /* and put on interrupt list if the pipe wasn't running */
2075 if (!err)
2076 uhci_device_isoc_start(SIMPLEQ_FIRST(&xfer->pipe->queue));
2077
2078 return (err);
2079 }
2080
2081 void
2082 uhci_device_isoc_enter(xfer)
2083 usbd_xfer_handle xfer;
2084 {
2085 struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
2086 usbd_device_handle dev = upipe->pipe.device;
2087 uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
2088 struct iso *iso = &upipe->u.iso;
2089 uhci_soft_td_t *std;
2090 u_int32_t buf, len, status;
2091 int s, i, next, nframes;
2092
2093 DPRINTFN(5,("uhci_device_isoc_enter: used=%d next=%d xfer=%p "
2094 "nframes=%d\n",
2095 iso->inuse, iso->next, xfer, xfer->nframes));
2096
2097 if (sc->sc_dying)
2098 return;
2099
2100 if (xfer->status == USBD_IN_PROGRESS) {
2101 /* This request has already been entered into the frame list */
2102 /* XXX */
2103 }
2104
2105 #ifdef DIAGNOSTIC
2106 if (iso->inuse >= UHCI_VFRAMELIST_COUNT)
2107 printf("uhci_device_isoc_enter: overflow!\n");
2108 #endif
2109
2110 next = iso->next;
2111 if (next == -1) {
2112 /* Not in use yet, schedule it a few frames ahead. */
2113 next = (UREAD2(sc, UHCI_FRNUM) + 3) % UHCI_VFRAMELIST_COUNT;
2114 DPRINTFN(2,("uhci_device_isoc_enter: start next=%d\n", next));
2115 }
2116
2117 xfer->status = USBD_IN_PROGRESS;
2118 xfer->hcprivint = next;
2119
2120 buf = DMAADDR(&xfer->dmabuf);
2121 status = LE(UHCI_TD_ZERO_ACTLEN(UHCI_TD_SET_ERRCNT(0) |
2122 UHCI_TD_ACTIVE |
2123 UHCI_TD_IOS));
2124 nframes = xfer->nframes;
2125 s = splusb();
2126 for (i = 0; i < nframes; i++) {
2127 std = iso->stds[next];
2128 if (++next >= UHCI_VFRAMELIST_COUNT)
2129 next = 0;
2130 len = xfer->frlengths[i];
2131 std->td.td_buffer = LE(buf);
2132 if (i == nframes - 1)
2133 status |= LE(UHCI_TD_IOC);
2134 std->td.td_status = status;
2135 std->td.td_token &= LE(~UHCI_TD_MAXLEN_MASK);
2136 std->td.td_token |= LE(UHCI_TD_SET_MAXLEN(len));
2137 #ifdef UHCI_DEBUG
2138 if (uhcidebug > 5) {
2139 DPRINTFN(5,("uhci_device_isoc_enter: TD %d\n", i));
2140 uhci_dump_td(std);
2141 }
2142 #endif
2143 buf += len;
2144 }
2145 iso->next = next;
2146 iso->inuse += xfer->nframes;
2147
2148 splx(s);
2149 }
2150
2151 usbd_status
2152 uhci_device_isoc_start(xfer)
2153 usbd_xfer_handle xfer;
2154 {
2155 struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
2156 uhci_softc_t *sc = (uhci_softc_t *)upipe->pipe.device->bus;
2157 uhci_intr_info_t *ii = upipe->iinfo;
2158 uhci_soft_td_t *end;
2159 int s, i;
2160
2161 if (sc->sc_dying)
2162 return (USBD_IOERROR);
2163
2164 #ifdef DIAGNOSTIC
2165 if (xfer->status != USBD_IN_PROGRESS)
2166 printf("uhci_device_isoc_start: not in progress %p\n", xfer);
2167 #endif
2168
2169 /* Find the last TD */
2170 i = xfer->hcprivint + xfer->nframes;
2171 if (i >= UHCI_VFRAMELIST_COUNT)
2172 i -= UHCI_VFRAMELIST_COUNT;
2173 end = upipe->u.iso.stds[i];
2174
2175 s = splusb();
2176
2177 /* Set up interrupt info. */
2178 ii->xfer = xfer;
2179 ii->stdstart = end;
2180 ii->stdend = end;
2181 #if defined(__FreeBSD__)
2182 callout_handle_init(&ii->timeout_handle);
2183 #endif
2184 #ifdef DIAGNOSTIC
2185 if (!ii->isdone) {
2186 printf("uhci_device_isoc_start: not done, ii=%p\n", ii);
2187 }
2188 ii->isdone = 0;
2189 #endif
2190 LIST_INSERT_HEAD(&sc->sc_intrhead, ii, list);
2191
2192 splx(s);
2193
2194 return (USBD_IN_PROGRESS);
2195 }
2196
2197 void
2198 uhci_device_isoc_abort(xfer)
2199 usbd_xfer_handle xfer;
2200 {
2201 struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
2202 uhci_intr_info_t *ii = upipe->iinfo;
2203 uhci_soft_td_t **stds = upipe->u.iso.stds;
2204 uhci_soft_td_t *std;
2205 int i, n, nframes;
2206
2207 /* Make interrupt routine ignore it, */
2208 xfer->status = USBD_CANCELLED;
2209
2210 /* make hardware ignore it, */
2211 nframes = xfer->nframes;
2212 n = xfer->hcprivint;
2213 for (i = 0; i < nframes; i++) {
2214 std = stds[n];
2215 std->td.td_status &= LE(~(UHCI_TD_ACTIVE | UHCI_TD_IOC));
2216 if (++n >= UHCI_VFRAMELIST_COUNT)
2217 n = 0;
2218 }
2219
2220 xfer->hcpriv = ii;
2221
2222 /* make sure hardware has completed, */
2223 if (xfer->device->bus->intr_context) {
2224 /* We have no process context, so we can't use tsleep(). */
2225 timeout(uhci_abort_xfer_end, xfer, hz / USB_FRAMES_PER_SECOND);
2226 } else {
2227 usb_delay_ms(xfer->pipe->device->bus, 1);
2228 /* and call final part of interrupt handler. */
2229 uhci_abort_xfer_end(xfer);
2230 }
2231 }
2232
2233 void
2234 uhci_device_isoc_close(pipe)
2235 usbd_pipe_handle pipe;
2236 {
2237 struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
2238 usbd_device_handle dev = upipe->pipe.device;
2239 uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
2240 uhci_soft_td_t *std, *vstd;
2241 struct iso *iso;
2242 int i;
2243
2244 /*
2245 * Make sure all TDs are marked as inactive.
2246 * Wait for completion.
2247 * Unschedule.
2248 * Deallocate.
2249 */
2250 iso = &upipe->u.iso;
2251
2252 for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++)
2253 iso->stds[i]->td.td_status &= LE(~UHCI_TD_ACTIVE);
2254 usb_delay_ms(&sc->sc_bus, 2); /* wait for completion */
2255
2256 uhci_lock_frames(sc);
2257 for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) {
2258 std = iso->stds[i];
2259 for (vstd = sc->sc_vframes[i].htd;
2260 vstd != NULL && vstd->link.std != std;
2261 vstd = vstd->link.std)
2262 ;
2263 if (vstd == NULL) {
2264 /*panic*/
2265 printf("uhci_device_isoc_close: %p not found\n", std);
2266 uhci_unlock_frames(sc);
2267 return;
2268 }
2269 vstd->link = std->link;
2270 vstd->td.td_link = std->td.td_link;
2271 uhci_free_std(sc, std);
2272 }
2273 uhci_unlock_frames(sc);
2274
2275 free(iso->stds, M_USBHC);
2276 }
2277
2278 usbd_status
2279 uhci_setup_isoc(pipe)
2280 usbd_pipe_handle pipe;
2281 {
2282 struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
2283 usbd_device_handle dev = upipe->pipe.device;
2284 uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
2285 int addr = upipe->pipe.device->address;
2286 int endpt = upipe->pipe.endpoint->edesc->bEndpointAddress;
2287 int rd = UE_GET_DIR(endpt) == UE_DIR_IN;
2288 uhci_soft_td_t *std, *vstd;
2289 u_int32_t token;
2290 struct iso *iso;
2291 int i;
2292
2293 iso = &upipe->u.iso;
2294 iso->stds = malloc(UHCI_VFRAMELIST_COUNT * sizeof (uhci_soft_td_t *),
2295 M_USBHC, M_WAITOK);
2296
2297 token = LE(rd ? UHCI_TD_IN (0, endpt, addr, 0) :
2298 UHCI_TD_OUT(0, endpt, addr, 0));
2299
2300 /* Allocate the TDs and mark as inactive; */
2301 for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) {
2302 std = uhci_alloc_std(sc);
2303 if (std == 0)
2304 goto bad;
2305 std->td.td_status = LE(UHCI_TD_IOS); /* iso, inactive */
2306 std->td.td_token = token;
2307 iso->stds[i] = std;
2308 }
2309
2310 /* Insert TDs into schedule. */
2311 uhci_lock_frames(sc);
2312 for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) {
2313 std = iso->stds[i];
2314 vstd = sc->sc_vframes[i].htd;
2315 std->link = vstd->link;
2316 std->td.td_link = vstd->td.td_link;
2317 vstd->link.std = std;
2318 vstd->td.td_link = LE(std->physaddr);
2319 }
2320 uhci_unlock_frames(sc);
2321
2322 iso->next = -1;
2323 iso->inuse = 0;
2324
2325 return (USBD_NORMAL_COMPLETION);
2326
2327 bad:
2328 while (--i >= 0)
2329 uhci_free_std(sc, iso->stds[i]);
2330 free(iso->stds, M_USBHC);
2331 return (USBD_NOMEM);
2332 }
2333
2334 void
2335 uhci_device_isoc_done(xfer)
2336 usbd_xfer_handle xfer;
2337 {
2338 uhci_intr_info_t *ii = xfer->hcpriv;
2339
2340 DPRINTFN(4, ("uhci_isoc_done: length=%d\n", xfer->actlen));
2341
2342 /* Turn off the interrupt since it is active even if the TD is not. */
2343 ii->stdend->td.td_status &= LE(~UHCI_TD_IOC);
2344
2345 LIST_REMOVE(ii, list); /* remove from active list */
2346 }
2347
2348 void
2349 uhci_device_intr_done(xfer)
2350 usbd_xfer_handle xfer;
2351 {
2352 uhci_intr_info_t *ii = xfer->hcpriv;
2353 uhci_softc_t *sc = ii->sc;
2354 struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
2355 uhci_soft_qh_t *sqh;
2356 int i, npoll;
2357
2358 DPRINTFN(5, ("uhci_intr_done: length=%d\n", xfer->actlen));
2359
2360 npoll = upipe->u.intr.npoll;
2361 for(i = 0; i < npoll; i++) {
2362 sqh = upipe->u.intr.qhs[i];
2363 sqh->elink = 0;
2364 sqh->qh.qh_elink = LE(UHCI_PTR_T);
2365 }
2366 uhci_free_std_chain(sc, ii->stdstart, 0);
2367
2368 /* XXX Wasteful. */
2369 if (xfer->pipe->repeat) {
2370 uhci_soft_td_t *data, *dataend;
2371
2372 /* This alloc cannot fail since we freed the chain above. */
2373 uhci_alloc_std_chain(upipe, sc, xfer->length, 1, xfer->flags,
2374 &xfer->dmabuf, &data, &dataend);
2375 dataend->td.td_status |= LE(UHCI_TD_IOC);
2376
2377 #ifdef UHCI_DEBUG
2378 if (uhcidebug > 10) {
2379 DPRINTF(("uhci_device_intr_done: data(1)\n"));
2380 uhci_dump_tds(data);
2381 uhci_dump_qh(upipe->u.intr.qhs[0]);
2382 }
2383 #endif
2384
2385 ii->stdstart = data;
2386 ii->stdend = dataend;
2387 #if defined(__FreeBSD__)
2388 callout_handle_init(&ii->timeout_handle);
2389 #endif
2390 #ifdef DIAGNOSTIC
2391 if (!ii->isdone) {
2392 printf("uhci_device_intr_done: not done, ii=%p\n", ii);
2393 }
2394 ii->isdone = 0;
2395 #endif
2396 for (i = 0; i < npoll; i++) {
2397 sqh = upipe->u.intr.qhs[i];
2398 sqh->elink = data;
2399 sqh->qh.qh_elink = LE(data->physaddr);
2400 }
2401 } else {
2402 ii->stdstart = 0; /* mark as inactive */
2403 }
2404 }
2405
2406 /* Deallocate request data structures */
2407 void
2408 uhci_device_ctrl_done(xfer)
2409 usbd_xfer_handle xfer;
2410 {
2411 uhci_intr_info_t *ii = xfer->hcpriv;
2412 uhci_softc_t *sc = ii->sc;
2413 struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
2414
2415 #ifdef DIAGNOSTIC
2416 if (!(xfer->rqflags & URQ_REQUEST))
2417 panic("uhci_ctrl_done: not a request\n");
2418 #endif
2419
2420 LIST_REMOVE(ii, list); /* remove from active list */
2421
2422 uhci_remove_ctrl(sc, upipe->u.ctl.sqh);
2423
2424 if (upipe->u.ctl.length != 0)
2425 uhci_free_std_chain(sc, ii->stdstart->link.std, ii->stdend);
2426
2427 DPRINTFN(5, ("uhci_ctrl_done: length=%d\n", xfer->actlen));
2428 }
2429
2430 /* Deallocate request data structures */
2431 void
2432 uhci_device_bulk_done(xfer)
2433 usbd_xfer_handle xfer;
2434 {
2435 uhci_intr_info_t *ii = xfer->hcpriv;
2436 uhci_softc_t *sc = ii->sc;
2437 struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
2438
2439 LIST_REMOVE(ii, list); /* remove from active list */
2440
2441 uhci_remove_bulk(sc, upipe->u.bulk.sqh);
2442
2443 uhci_free_std_chain(sc, ii->stdstart, 0);
2444
2445 DPRINTFN(5, ("uhci_bulk_done: length=%d\n", xfer->actlen));
2446 }
2447
2448 /* Add interrupt QH, called with vflock. */
2449 void
2450 uhci_add_intr(sc, n, sqh)
2451 uhci_softc_t *sc;
2452 int n;
2453 uhci_soft_qh_t *sqh;
2454 {
2455 struct uhci_vframe *vf = &sc->sc_vframes[n];
2456 uhci_soft_qh_t *eqh;
2457
2458 DPRINTFN(4, ("uhci_add_intr: n=%d sqh=%p\n", n, sqh));
2459 eqh = vf->eqh;
2460 sqh->hlink = eqh->hlink;
2461 sqh->qh.qh_hlink = eqh->qh.qh_hlink;
2462 eqh->hlink = sqh;
2463 eqh->qh.qh_hlink = LE(sqh->physaddr | UHCI_PTR_Q);
2464 vf->eqh = sqh;
2465 vf->bandwidth++;
2466 }
2467
2468 /* Remove interrupt QH, called with vflock. */
2469 void
2470 uhci_remove_intr(sc, n, sqh)
2471 uhci_softc_t *sc;
2472 int n;
2473 uhci_soft_qh_t *sqh;
2474 {
2475 struct uhci_vframe *vf = &sc->sc_vframes[n];
2476 uhci_soft_qh_t *pqh;
2477
2478 DPRINTFN(4, ("uhci_remove_intr: n=%d sqh=%p\n", n, sqh));
2479
2480 for (pqh = vf->hqh; pqh->hlink != sqh; pqh = pqh->hlink)
2481 #if defined(DIAGNOSTIC) || defined(UHCI_DEBUG)
2482 if (LE(pqh->qh.qh_hlink) & UHCI_PTR_T) {
2483 DPRINTF(("uhci_remove_intr: QH not found\n"));
2484 return;
2485 }
2486 #else
2487 ;
2488 #endif
2489 pqh->hlink = sqh->hlink;
2490 pqh->qh.qh_hlink = sqh->qh.qh_hlink;
2491 if (vf->eqh == sqh)
2492 vf->eqh = pqh;
2493 vf->bandwidth--;
2494 }
2495
2496 usbd_status
2497 uhci_device_setintr(sc, upipe, ival)
2498 uhci_softc_t *sc;
2499 struct uhci_pipe *upipe;
2500 int ival;
2501 {
2502 uhci_soft_qh_t *sqh;
2503 int i, npoll, s;
2504 u_int bestbw, bw, bestoffs, offs;
2505
2506 DPRINTFN(2, ("uhci_setintr: pipe=%p\n", upipe));
2507 if (ival == 0) {
2508 printf("uhci_setintr: 0 interval\n");
2509 return (USBD_INVAL);
2510 }
2511
2512 if (ival > UHCI_VFRAMELIST_COUNT)
2513 ival = UHCI_VFRAMELIST_COUNT;
2514 npoll = (UHCI_VFRAMELIST_COUNT + ival - 1) / ival;
2515 DPRINTFN(2, ("uhci_setintr: ival=%d npoll=%d\n", ival, npoll));
2516
2517 upipe->u.intr.npoll = npoll;
2518 upipe->u.intr.qhs =
2519 malloc(npoll * sizeof(uhci_soft_qh_t *), M_USBHC, M_WAITOK);
2520
2521 /*
2522 * Figure out which offset in the schedule that has most
2523 * bandwidth left over.
2524 */
2525 #define MOD(i) ((i) & (UHCI_VFRAMELIST_COUNT-1))
2526 for (bestoffs = offs = 0, bestbw = ~0; offs < ival; offs++) {
2527 for (bw = i = 0; i < npoll; i++)
2528 bw += sc->sc_vframes[MOD(i * ival + offs)].bandwidth;
2529 if (bw < bestbw) {
2530 bestbw = bw;
2531 bestoffs = offs;
2532 }
2533 }
2534 DPRINTFN(1, ("uhci_setintr: bw=%d offs=%d\n", bestbw, bestoffs));
2535
2536 upipe->iinfo->stdstart = 0;
2537 for(i = 0; i < npoll; i++) {
2538 upipe->u.intr.qhs[i] = sqh = uhci_alloc_sqh(sc);
2539 sqh->elink = 0;
2540 sqh->qh.qh_elink = LE(UHCI_PTR_T);
2541 sqh->pos = MOD(i * ival + bestoffs);
2542 sqh->intr_info = upipe->iinfo;
2543 }
2544 #undef MOD
2545
2546 s = splusb();
2547 LIST_INSERT_HEAD(&sc->sc_intrhead, upipe->iinfo, list);
2548 splx(s);
2549
2550 uhci_lock_frames(sc);
2551 /* Enter QHs into the controller data structures. */
2552 for(i = 0; i < npoll; i++)
2553 uhci_add_intr(sc, upipe->u.intr.qhs[i]->pos,
2554 upipe->u.intr.qhs[i]);
2555 uhci_unlock_frames(sc);
2556
2557 DPRINTFN(5, ("uhci_setintr: returns %p\n", upipe));
2558 return (USBD_NORMAL_COMPLETION);
2559 }
2560
2561 /* Open a new pipe. */
2562 usbd_status
2563 uhci_open(pipe)
2564 usbd_pipe_handle pipe;
2565 {
2566 uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus;
2567 struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
2568 usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc;
2569 usbd_status err;
2570 int ival;
2571
2572 DPRINTFN(1, ("uhci_open: pipe=%p, addr=%d, endpt=%d (%d)\n",
2573 pipe, pipe->device->address,
2574 ed->bEndpointAddress, sc->sc_addr));
2575 if (pipe->device->address == sc->sc_addr) {
2576 switch (ed->bEndpointAddress) {
2577 case USB_CONTROL_ENDPOINT:
2578 pipe->methods = &uhci_root_ctrl_methods;
2579 break;
2580 case UE_DIR_IN | UHCI_INTR_ENDPT:
2581 pipe->methods = &uhci_root_intr_methods;
2582 break;
2583 default:
2584 return (USBD_INVAL);
2585 }
2586 } else {
2587 upipe->iinfo = uhci_alloc_intr_info(sc);
2588 if (upipe->iinfo == 0)
2589 return (USBD_NOMEM);
2590 switch (ed->bmAttributes & UE_XFERTYPE) {
2591 case UE_CONTROL:
2592 pipe->methods = &uhci_device_ctrl_methods;
2593 upipe->u.ctl.sqh = uhci_alloc_sqh(sc);
2594 if (upipe->u.ctl.sqh == NULL)
2595 goto bad;
2596 upipe->u.ctl.setup = uhci_alloc_std(sc);
2597 if (upipe->u.ctl.setup == NULL) {
2598 uhci_free_sqh(sc, upipe->u.ctl.sqh);
2599 goto bad;
2600 }
2601 upipe->u.ctl.stat = uhci_alloc_std(sc);
2602 if (upipe->u.ctl.stat == NULL) {
2603 uhci_free_sqh(sc, upipe->u.ctl.sqh);
2604 uhci_free_std(sc, upipe->u.ctl.setup);
2605 goto bad;
2606 }
2607 err = usb_allocmem(&sc->sc_bus,
2608 sizeof(usb_device_request_t),
2609 0, &upipe->u.ctl.reqdma);
2610 if (err) {
2611 uhci_free_sqh(sc, upipe->u.ctl.sqh);
2612 uhci_free_std(sc, upipe->u.ctl.setup);
2613 uhci_free_std(sc, upipe->u.ctl.stat);
2614 goto bad;
2615 }
2616 break;
2617 case UE_INTERRUPT:
2618 pipe->methods = &uhci_device_intr_methods;
2619 ival = pipe->interval;
2620 if (ival == USBD_DEFAULT_INTERVAL)
2621 ival = ed->bInterval;
2622 return (uhci_device_setintr(sc, upipe, ival));
2623 case UE_ISOCHRONOUS:
2624 pipe->methods = &uhci_device_isoc_methods;
2625 return (uhci_setup_isoc(pipe));
2626 case UE_BULK:
2627 pipe->methods = &uhci_device_bulk_methods;
2628 upipe->u.bulk.sqh = uhci_alloc_sqh(sc);
2629 if (upipe->u.bulk.sqh == NULL)
2630 goto bad;
2631 break;
2632 }
2633 }
2634 return (USBD_NORMAL_COMPLETION);
2635
2636 bad:
2637 uhci_free_intr_info(upipe->iinfo);
2638 return (USBD_NOMEM);
2639 }
2640
2641 /*
2642 * Data structures and routines to emulate the root hub.
2643 */
2644 usb_device_descriptor_t uhci_devd = {
2645 USB_DEVICE_DESCRIPTOR_SIZE,
2646 UDESC_DEVICE, /* type */
2647 {0x00, 0x01}, /* USB version */
2648 UCLASS_HUB, /* class */
2649 USUBCLASS_HUB, /* subclass */
2650 0, /* protocol */
2651 64, /* max packet */
2652 {0},{0},{0x00,0x01}, /* device id */
2653 1,2,0, /* string indicies */
2654 1 /* # of configurations */
2655 };
2656
2657 usb_config_descriptor_t uhci_confd = {
2658 USB_CONFIG_DESCRIPTOR_SIZE,
2659 UDESC_CONFIG,
2660 {USB_CONFIG_DESCRIPTOR_SIZE +
2661 USB_INTERFACE_DESCRIPTOR_SIZE +
2662 USB_ENDPOINT_DESCRIPTOR_SIZE},
2663 1,
2664 1,
2665 0,
2666 UC_SELF_POWERED,
2667 0 /* max power */
2668 };
2669
2670 usb_interface_descriptor_t uhci_ifcd = {
2671 USB_INTERFACE_DESCRIPTOR_SIZE,
2672 UDESC_INTERFACE,
2673 0,
2674 0,
2675 1,
2676 UCLASS_HUB,
2677 USUBCLASS_HUB,
2678 0,
2679 0
2680 };
2681
2682 usb_endpoint_descriptor_t uhci_endpd = {
2683 USB_ENDPOINT_DESCRIPTOR_SIZE,
2684 UDESC_ENDPOINT,
2685 UE_DIR_IN | UHCI_INTR_ENDPT,
2686 UE_INTERRUPT,
2687 {8},
2688 255
2689 };
2690
2691 usb_hub_descriptor_t uhci_hubd_piix = {
2692 USB_HUB_DESCRIPTOR_SIZE,
2693 UDESC_HUB,
2694 2,
2695 { UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL, 0 },
2696 50, /* power on to power good */
2697 0,
2698 { 0x00 }, /* both ports are removable */
2699 };
2700
2701 int
2702 uhci_str(p, l, s)
2703 usb_string_descriptor_t *p;
2704 int l;
2705 char *s;
2706 {
2707 int i;
2708
2709 if (l == 0)
2710 return (0);
2711 p->bLength = 2 * strlen(s) + 2;
2712 if (l == 1)
2713 return (1);
2714 p->bDescriptorType = UDESC_STRING;
2715 l -= 2;
2716 for (i = 0; s[i] && l > 1; i++, l -= 2)
2717 USETW2(p->bString[i], 0, s[i]);
2718 return (2*i+2);
2719 }
2720
2721 /*
2722 * Simulate a hardware hub by handling all the necessary requests.
2723 */
2724 usbd_status
2725 uhci_root_ctrl_transfer(xfer)
2726 usbd_xfer_handle xfer;
2727 {
2728 usbd_status err;
2729
2730 /* Insert last in queue. */
2731 err = usb_insert_transfer(xfer);
2732 if (err)
2733 return (err);
2734
2735 /* Pipe isn't running (otherwise err would be USBD_INPROG),
2736 * start first
2737 */
2738 return (uhci_root_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
2739 }
2740
2741 usbd_status
2742 uhci_root_ctrl_start(xfer)
2743 usbd_xfer_handle xfer;
2744 {
2745 uhci_softc_t *sc = (uhci_softc_t *)xfer->pipe->device->bus;
2746 usb_device_request_t *req;
2747 void *buf = NULL;
2748 int port, x;
2749 int s, len, value, index, status, change, l, totlen = 0;
2750 usb_port_status_t ps;
2751 usbd_status err;
2752
2753 if (sc->sc_dying)
2754 return (USBD_IOERROR);
2755
2756 #ifdef DIAGNOSTIC
2757 if (!(xfer->rqflags & URQ_REQUEST))
2758 panic("uhci_root_ctrl_transfer: not a request\n");
2759 #endif
2760 req = &xfer->request;
2761
2762 DPRINTFN(2,("uhci_root_ctrl_control type=0x%02x request=%02x\n",
2763 req->bmRequestType, req->bRequest));
2764
2765 len = UGETW(req->wLength);
2766 value = UGETW(req->wValue);
2767 index = UGETW(req->wIndex);
2768
2769 if (len != 0)
2770 buf = KERNADDR(&xfer->dmabuf);
2771
2772 #define C(x,y) ((x) | ((y) << 8))
2773 switch(C(req->bRequest, req->bmRequestType)) {
2774 case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE):
2775 case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE):
2776 case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT):
2777 /*
2778 * DEVICE_REMOTE_WAKEUP and ENDPOINT_HALT are no-ops
2779 * for the integrated root hub.
2780 */
2781 break;
2782 case C(UR_GET_CONFIG, UT_READ_DEVICE):
2783 if (len > 0) {
2784 *(u_int8_t *)buf = sc->sc_conf;
2785 totlen = 1;
2786 }
2787 break;
2788 case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
2789 DPRINTFN(2,("uhci_root_ctrl_control wValue=0x%04x\n", value));
2790 switch(value >> 8) {
2791 case UDESC_DEVICE:
2792 if ((value & 0xff) != 0) {
2793 err = USBD_IOERROR;
2794 goto ret;
2795 }
2796 totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE);
2797 USETW(uhci_devd.idVendor, sc->sc_id_vendor);
2798 memcpy(buf, &uhci_devd, l);
2799 break;
2800 case UDESC_CONFIG:
2801 if ((value & 0xff) != 0) {
2802 err = USBD_IOERROR;
2803 goto ret;
2804 }
2805 totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE);
2806 memcpy(buf, &uhci_confd, l);
2807 buf = (char *)buf + l;
2808 len -= l;
2809 l = min(len, USB_INTERFACE_DESCRIPTOR_SIZE);
2810 totlen += l;
2811 memcpy(buf, &uhci_ifcd, l);
2812 buf = (char *)buf + l;
2813 len -= l;
2814 l = min(len, USB_ENDPOINT_DESCRIPTOR_SIZE);
2815 totlen += l;
2816 memcpy(buf, &uhci_endpd, l);
2817 break;
2818 case UDESC_STRING:
2819 if (len == 0)
2820 break;
2821 *(u_int8_t *)buf = 0;
2822 totlen = 1;
2823 switch (value & 0xff) {
2824 case 1: /* Vendor */
2825 totlen = uhci_str(buf, len, sc->sc_vendor);
2826 break;
2827 case 2: /* Product */
2828 totlen = uhci_str(buf, len, "UHCI root hub");
2829 break;
2830 }
2831 break;
2832 default:
2833 err = USBD_IOERROR;
2834 goto ret;
2835 }
2836 break;
2837 case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
2838 if (len > 0) {
2839 *(u_int8_t *)buf = 0;
2840 totlen = 1;
2841 }
2842 break;
2843 case C(UR_GET_STATUS, UT_READ_DEVICE):
2844 if (len > 1) {
2845 USETW(((usb_status_t *)buf)->wStatus,UDS_SELF_POWERED);
2846 totlen = 2;
2847 }
2848 break;
2849 case C(UR_GET_STATUS, UT_READ_INTERFACE):
2850 case C(UR_GET_STATUS, UT_READ_ENDPOINT):
2851 if (len > 1) {
2852 USETW(((usb_status_t *)buf)->wStatus, 0);
2853 totlen = 2;
2854 }
2855 break;
2856 case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
2857 if (value >= USB_MAX_DEVICES) {
2858 err = USBD_IOERROR;
2859 goto ret;
2860 }
2861 sc->sc_addr = value;
2862 break;
2863 case C(UR_SET_CONFIG, UT_WRITE_DEVICE):
2864 if (value != 0 && value != 1) {
2865 err = USBD_IOERROR;
2866 goto ret;
2867 }
2868 sc->sc_conf = value;
2869 break;
2870 case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE):
2871 break;
2872 case C(UR_SET_FEATURE, UT_WRITE_DEVICE):
2873 case C(UR_SET_FEATURE, UT_WRITE_INTERFACE):
2874 case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
2875 err = USBD_IOERROR;
2876 goto ret;
2877 case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
2878 break;
2879 case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT):
2880 break;
2881 /* Hub requests */
2882 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE):
2883 break;
2884 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER):
2885 DPRINTFN(3, ("uhci_root_ctrl_control: UR_CLEAR_PORT_FEATURE "
2886 "port=%d feature=%d\n",
2887 index, value));
2888 if (index == 1)
2889 port = UHCI_PORTSC1;
2890 else if (index == 2)
2891 port = UHCI_PORTSC2;
2892 else {
2893 err = USBD_IOERROR;
2894 goto ret;
2895 }
2896 switch(value) {
2897 case UHF_PORT_ENABLE:
2898 x = UREAD2(sc, port);
2899 UWRITE2(sc, port, x & ~UHCI_PORTSC_PE);
2900 break;
2901 case UHF_PORT_SUSPEND:
2902 x = UREAD2(sc, port);
2903 UWRITE2(sc, port, x & ~UHCI_PORTSC_SUSP);
2904 break;
2905 case UHF_PORT_RESET:
2906 x = UREAD2(sc, port);
2907 UWRITE2(sc, port, x & ~UHCI_PORTSC_PR);
2908 break;
2909 case UHF_C_PORT_CONNECTION:
2910 x = UREAD2(sc, port);
2911 UWRITE2(sc, port, x | UHCI_PORTSC_CSC);
2912 break;
2913 case UHF_C_PORT_ENABLE:
2914 x = UREAD2(sc, port);
2915 UWRITE2(sc, port, x | UHCI_PORTSC_POEDC);
2916 break;
2917 case UHF_C_PORT_OVER_CURRENT:
2918 x = UREAD2(sc, port);
2919 UWRITE2(sc, port, x | UHCI_PORTSC_OCIC);
2920 break;
2921 case UHF_C_PORT_RESET:
2922 sc->sc_isreset = 0;
2923 err = USBD_NORMAL_COMPLETION;
2924 goto ret;
2925 case UHF_PORT_CONNECTION:
2926 case UHF_PORT_OVER_CURRENT:
2927 case UHF_PORT_POWER:
2928 case UHF_PORT_LOW_SPEED:
2929 case UHF_C_PORT_SUSPEND:
2930 default:
2931 err = USBD_IOERROR;
2932 goto ret;
2933 }
2934 break;
2935 case C(UR_GET_BUS_STATE, UT_READ_CLASS_OTHER):
2936 if (index == 1)
2937 port = UHCI_PORTSC1;
2938 else if (index == 2)
2939 port = UHCI_PORTSC2;
2940 else {
2941 err = USBD_IOERROR;
2942 goto ret;
2943 }
2944 if (len > 0) {
2945 *(u_int8_t *)buf =
2946 (UREAD2(sc, port) & UHCI_PORTSC_LS) >>
2947 UHCI_PORTSC_LS_SHIFT;
2948 totlen = 1;
2949 }
2950 break;
2951 case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
2952 if (value != 0) {
2953 err = USBD_IOERROR;
2954 goto ret;
2955 }
2956 l = min(len, USB_HUB_DESCRIPTOR_SIZE);
2957 totlen = l;
2958 memcpy(buf, &uhci_hubd_piix, l);
2959 break;
2960 case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
2961 if (len != 4) {
2962 err = USBD_IOERROR;
2963 goto ret;
2964 }
2965 memset(buf, 0, len);
2966 totlen = len;
2967 break;
2968 case C(UR_GET_STATUS, UT_READ_CLASS_OTHER):
2969 if (index == 1)
2970 port = UHCI_PORTSC1;
2971 else if (index == 2)
2972 port = UHCI_PORTSC2;
2973 else {
2974 err = USBD_IOERROR;
2975 goto ret;
2976 }
2977 if (len != 4) {
2978 err = USBD_IOERROR;
2979 goto ret;
2980 }
2981 x = UREAD2(sc, port);
2982 status = change = 0;
2983 if (x & UHCI_PORTSC_CCS )
2984 status |= UPS_CURRENT_CONNECT_STATUS;
2985 if (x & UHCI_PORTSC_CSC )
2986 change |= UPS_C_CONNECT_STATUS;
2987 if (x & UHCI_PORTSC_PE )
2988 status |= UPS_PORT_ENABLED;
2989 if (x & UHCI_PORTSC_POEDC)
2990 change |= UPS_C_PORT_ENABLED;
2991 if (x & UHCI_PORTSC_OCI )
2992 status |= UPS_OVERCURRENT_INDICATOR;
2993 if (x & UHCI_PORTSC_OCIC )
2994 change |= UPS_C_OVERCURRENT_INDICATOR;
2995 if (x & UHCI_PORTSC_SUSP )
2996 status |= UPS_SUSPEND;
2997 if (x & UHCI_PORTSC_LSDA )
2998 status |= UPS_LOW_SPEED;
2999 status |= UPS_PORT_POWER;
3000 if (sc->sc_isreset)
3001 change |= UPS_C_PORT_RESET;
3002 USETW(ps.wPortStatus, status);
3003 USETW(ps.wPortChange, change);
3004 l = min(len, sizeof ps);
3005 memcpy(buf, &ps, l);
3006 totlen = l;
3007 break;
3008 case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
3009 err = USBD_IOERROR;
3010 goto ret;
3011 case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE):
3012 break;
3013 case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER):
3014 if (index == 1)
3015 port = UHCI_PORTSC1;
3016 else if (index == 2)
3017 port = UHCI_PORTSC2;
3018 else {
3019 err = USBD_IOERROR;
3020 goto ret;
3021 }
3022 switch(value) {
3023 case UHF_PORT_ENABLE:
3024 x = UREAD2(sc, port);
3025 UWRITE2(sc, port, x | UHCI_PORTSC_PE);
3026 break;
3027 case UHF_PORT_SUSPEND:
3028 x = UREAD2(sc, port);
3029 UWRITE2(sc, port, x | UHCI_PORTSC_SUSP);
3030 break;
3031 case UHF_PORT_RESET:
3032 x = UREAD2(sc, port);
3033 UWRITE2(sc, port, x | UHCI_PORTSC_PR);
3034 usb_delay_ms(&sc->sc_bus, 10);
3035 UWRITE2(sc, port, x & ~UHCI_PORTSC_PR);
3036 delay(100);
3037 x = UREAD2(sc, port);
3038 UWRITE2(sc, port, x | UHCI_PORTSC_PE);
3039 delay(100);
3040 DPRINTFN(3,("uhci port %d reset, status = 0x%04x\n",
3041 index, UREAD2(sc, port)));
3042 sc->sc_isreset = 1;
3043 break;
3044 case UHF_C_PORT_CONNECTION:
3045 case UHF_C_PORT_ENABLE:
3046 case UHF_C_PORT_OVER_CURRENT:
3047 case UHF_PORT_CONNECTION:
3048 case UHF_PORT_OVER_CURRENT:
3049 case UHF_PORT_POWER:
3050 case UHF_PORT_LOW_SPEED:
3051 case UHF_C_PORT_SUSPEND:
3052 case UHF_C_PORT_RESET:
3053 default:
3054 err = USBD_IOERROR;
3055 goto ret;
3056 }
3057 break;
3058 default:
3059 err = USBD_IOERROR;
3060 goto ret;
3061 }
3062 xfer->actlen = totlen;
3063 err = USBD_NORMAL_COMPLETION;
3064 ret:
3065 xfer->status = err;
3066 xfer->hcpriv = 0;
3067 s = splusb();
3068 usb_transfer_complete(xfer);
3069 splx(s);
3070 return (USBD_IN_PROGRESS);
3071 }
3072
3073 /* Abort a root control request. */
3074 void
3075 uhci_root_ctrl_abort(xfer)
3076 usbd_xfer_handle xfer;
3077 {
3078 /* Nothing to do, all transfers are synchronous. */
3079 }
3080
3081 /* Close the root pipe. */
3082 void
3083 uhci_root_ctrl_close(pipe)
3084 usbd_pipe_handle pipe;
3085 {
3086 DPRINTF(("uhci_root_ctrl_close\n"));
3087 }
3088
3089 /* Abort a root interrupt request. */
3090 void
3091 uhci_root_intr_abort(xfer)
3092 usbd_xfer_handle xfer;
3093 {
3094 uhci_softc_t *sc = (uhci_softc_t *)xfer->pipe->device->bus;
3095
3096 usb_untimeout(uhci_timo, xfer, xfer->timo_handle);
3097 sc->sc_has_timo = NULL;
3098
3099 if (xfer->pipe->intrxfer == xfer) {
3100 DPRINTF(("uhci_root_intr_abort: remove\n"));
3101 xfer->pipe->intrxfer = 0;
3102 }
3103 xfer->status = USBD_CANCELLED;
3104 usb_transfer_complete(xfer);
3105 }
3106
3107 usbd_status
3108 uhci_root_intr_transfer(xfer)
3109 usbd_xfer_handle xfer;
3110 {
3111 usbd_status err;
3112
3113 /* Insert last in queue. */
3114 err = usb_insert_transfer(xfer);
3115 if (err)
3116 return (err);
3117
3118 /* Pipe isn't running (otherwise err would be USBD_INPROG),
3119 * start first
3120 */
3121 return (uhci_root_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
3122 }
3123
3124 /* Start a transfer on the root interrupt pipe */
3125 usbd_status
3126 uhci_root_intr_start(xfer)
3127 usbd_xfer_handle xfer;
3128 {
3129 usbd_pipe_handle pipe = xfer->pipe;
3130 uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus;
3131
3132 DPRINTFN(3, ("uhci_root_intr_transfer: xfer=%p len=%d flags=%d\n",
3133 xfer, xfer->length, xfer->flags));
3134
3135 if (sc->sc_dying)
3136 return (USBD_IOERROR);
3137
3138 sc->sc_ival = MS_TO_TICKS(xfer->pipe->endpoint->edesc->bInterval);
3139 usb_timeout(uhci_timo, xfer, sc->sc_ival, xfer->timo_handle);
3140 sc->sc_has_timo = xfer;
3141 return (USBD_IN_PROGRESS);
3142 }
3143
3144 /* Close the root interrupt pipe. */
3145 void
3146 uhci_root_intr_close(pipe)
3147 usbd_pipe_handle pipe;
3148 {
3149 uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus;
3150
3151 usb_untimeout(uhci_timo, pipe->intrxfer, pipe->intrxfer->timo_handle);
3152 sc->sc_has_timo = NULL;
3153 DPRINTF(("uhci_root_intr_close\n"));
3154 }
3155