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