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