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