]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/usb/uhci.c
This commit was generated by cvs2svn to compensate for changes in r41461,
[FreeBSD/FreeBSD.git] / sys / dev / usb / uhci.c
1 /*      $NetBSD: uhci.c,v 1.10 1998/08/02 22:30:52 augustss Exp $       */
2
3 /*
4  * Copyright (c) 1998 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * Author: Lennart Augustsson <augustss@carlstedt.se>
8  *         Carlstedt Research & Technology
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *        This product includes software developed by the NetBSD
21  *        Foundation, Inc. and its contributors.
22  * 4. Neither the name of The NetBSD Foundation nor the names of its
23  *    contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  */
38
39 /*
40  * USB Universal Host Controller driver.
41  * Handles PIIX3 and PIIX4.
42  *
43  * Data sheets: ftp://download.intel.com/design/intarch/datashts/29055002.pdf
44  *              ftp://download.intel.com/design/intarch/datashts/29056201.pdf
45  * UHCI spec: http://www.intel.com/design/usb/uhci11d.pdf
46  * USB spec: http://www.teleport.com/cgi-bin/mailmerge.cgi/~usb/cgiform.tpl
47  */
48
49 #include <dev/usb/usb_port.h>
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__)
56 #include <sys/device.h>
57 #elif defined(__FreeBSD__)
58 #include <sys/module.h>
59 #include <sys/bus.h>
60 #endif
61 #include <sys/proc.h>
62 #include <sys/queue.h>
63 #include <sys/select.h>
64
65 #include <machine/bus.h>
66
67 #include <dev/usb/usb.h>
68 #include <dev/usb/usbdi.h>
69 #include <dev/usb/usbdivar.h>
70 #include <dev/usb/usb_mem.h>
71 #include <dev/usb/usb_quirks.h>
72
73 #include <dev/usb/uhcireg.h>
74 #include <dev/usb/uhcivar.h>
75
76 #if defined(__FreeBSD__)
77 #include <machine/clock.h>
78 #include "dev/usb/queue.addendum.h"
79
80 #define delay(d)                DELAY(d)
81
82 static struct callout_handle uhci_timeout_handle
83         = CALLOUT_HANDLE_INITIALIZER(&uhci_timeout_handle);
84 static struct callout_handle uhci_timo_handle
85         = CALLOUT_HANDLE_INITIALIZER(&uhci_timo_handle);
86 #endif
87
88 #define MS_TO_TICKS(ms) ((ms) * hz / 1000)
89
90 struct uhci_pipe {
91         struct usbd_pipe pipe;
92         uhci_intr_info_t *iinfo;
93         int newtoggle;
94         /* Info needed for different pipe kinds. */
95         union {
96                 /* Control pipe */
97                 struct {
98                         uhci_soft_qh_t *sqh;
99                         usb_dma_t reqdma;
100                         usb_dma_t datadma;
101                         uhci_soft_td_t *setup, *stat, *xferend;
102                         u_int length;
103                 } ctl;
104                 /* Interrupt pipe */
105                 struct {
106                         usb_dma_t datadma;
107                         int npoll;
108                         uhci_soft_qh_t **qhs;
109                 } intr;
110                 /* Bulk pipe */
111                 struct {
112                         uhci_soft_qh_t *sqh;
113                         usb_dma_t datadma;
114                         u_int length;
115                         int isread;
116                 } bulk;
117         } u;
118 };
119
120 /* 
121  * The uhci_intr_info free list can be global since they contain
122  * no dma specific data.  The other free lists do.
123  */
124 LIST_HEAD(, uhci_intr_info) uhci_ii_free;
125
126 void            uhci_busreset __P((uhci_softc_t *));
127 void            uhci_run __P((uhci_softc_t *, int run));
128 uhci_soft_td_t *uhci_alloc_std __P((uhci_softc_t *));
129 void            uhci_free_std __P((uhci_softc_t *, uhci_soft_td_t *));
130 uhci_soft_qh_t *uhci_alloc_sqh __P((uhci_softc_t *));
131 void            uhci_free_sqh __P((uhci_softc_t *, uhci_soft_qh_t *));
132 uhci_intr_info_t *uhci_alloc_intr_info __P((uhci_softc_t *));
133 void            uhci_free_intr_info __P((uhci_intr_info_t *ii));
134 void            uhci_enter_ctl_q __P((uhci_softc_t *, uhci_soft_qh_t *,
135                                       uhci_intr_info_t *));
136 void            uhci_exit_ctl_q __P((uhci_softc_t *, uhci_soft_qh_t *));
137
138 void            uhci_free_std_chain __P((uhci_softc_t *, 
139                                          uhci_soft_td_t *, uhci_soft_td_t *));
140 usbd_status     uhci_alloc_std_chain __P((struct uhci_pipe *, uhci_softc_t *,
141                                           int, int, usb_dma_t *, 
142                                           uhci_soft_td_t **,
143                                           uhci_soft_td_t **));
144 void            uhci_timo __P((void *));
145 void            uhci_waitintr __P((uhci_softc_t *, usbd_request_handle));
146 void            uhci_check_intr __P((uhci_softc_t *, uhci_intr_info_t *));
147 void            uhci_ii_done __P((uhci_intr_info_t *, int));
148 void            uhci_timeout __P((void *));
149 void            uhci_wakeup_ctrl __P((void *, int, int, void *, int));
150 void            uhci_lock_frames __P((uhci_softc_t *));
151 void            uhci_unlock_frames __P((uhci_softc_t *));
152 void            uhci_add_ctrl __P((uhci_softc_t *, uhci_soft_qh_t *));
153 void            uhci_add_bulk __P((uhci_softc_t *, uhci_soft_qh_t *));
154 void            uhci_remove_ctrl __P((uhci_softc_t *, uhci_soft_qh_t *));
155 void            uhci_remove_bulk __P((uhci_softc_t *, uhci_soft_qh_t *));
156 int             uhci_str __P((usb_string_descriptor_t *, int, char *));
157
158 void            uhci_device_close __P((struct uhci_pipe *));
159
160 void            uhci_wakeup_cb __P((usbd_request_handle reqh));
161
162 usbd_status     uhci_device_ctrl_transfer __P((usbd_request_handle));
163 void            uhci_device_ctrl_abort __P((usbd_request_handle));
164 void            uhci_device_ctrl_close __P((usbd_pipe_handle));
165 usbd_status     uhci_device_intr_transfer __P((usbd_request_handle));
166 void            uhci_device_intr_abort __P((usbd_request_handle));
167 void            uhci_device_intr_close __P((usbd_pipe_handle));
168 usbd_status     uhci_device_bulk_transfer __P((usbd_request_handle));
169 void            uhci_device_bulk_abort __P((usbd_request_handle));
170 void            uhci_device_bulk_close __P((usbd_pipe_handle));
171
172 usbd_status     uhci_root_ctrl_transfer __P((usbd_request_handle));
173 void            uhci_root_ctrl_abort __P((usbd_request_handle));
174 void            uhci_root_ctrl_close __P((usbd_pipe_handle));
175 usbd_status     uhci_root_intr_transfer __P((usbd_request_handle));
176 void            uhci_root_intr_abort __P((usbd_request_handle));
177 void            uhci_root_intr_close __P((usbd_pipe_handle));
178
179 usbd_status     uhci_open __P((usbd_pipe_handle));
180 void            uhci_poll __P((struct usbd_bus *));
181
182 usbd_status     uhci_device_request __P((usbd_request_handle reqh));
183 void            uhci_ctrl_done __P((uhci_intr_info_t *ii));
184 void            uhci_bulk_done __P((uhci_intr_info_t *ii));
185
186 void            uhci_add_intr __P((uhci_softc_t *, int, uhci_soft_qh_t *));
187 void            uhci_remove_intr __P((uhci_softc_t *, int, uhci_soft_qh_t *));
188 usbd_status     uhci_device_setintr __P((uhci_softc_t *sc, 
189                                          struct uhci_pipe *pipe, int ival));
190 void            uhci_intr_done __P((uhci_intr_info_t *ii));
191
192 #ifdef USB_DEBUG
193 static void     uhci_dumpregs __P((uhci_softc_t *));
194 void            uhci_dump_tds __P((uhci_soft_td_t *));
195 void            uhci_dump_qh __P((uhci_soft_qh_t *));
196 void            uhci_dump __P((void));
197 void            uhci_dump_td __P((uhci_soft_td_t *));
198 #endif
199
200 #if defined(__NetBSD__)
201 #define UWRITE2(sc, r, x) bus_space_write_2((sc)->iot, (sc)->ioh, (r), (x))
202 #define UWRITE4(sc, r, x) bus_space_write_4((sc)->iot, (sc)->ioh, (r), (x))
203 #define UREAD2(sc, r) bus_space_read_2((sc)->iot, (sc)->ioh, (r))
204 #define UREAD4(sc, r) bus_space_read_4((sc)->iot, (sc)->ioh, (r))
205 #elif defined(__FreeBSD__)
206 #define UWRITE2(sc,r,x) outw((sc)->sc_iobase + (r), (x))
207 #define UWRITE4(sc,r,x) outl((sc)->sc_iobase + (r), (x))
208 #define UREAD2(sc,r)    inw((sc)->sc_iobase + (r))
209 #define UREAD4(sc,r)    inl((sc)->sc_iobase + (r))
210 #endif
211
212 #define UHCICMD(sc, cmd) UWRITE2(sc, UHCI_CMD, cmd)
213 #define UHCISTS(sc) UREAD2(sc, UHCI_STS)
214
215 #define UHCI_RESET_TIMEOUT 100  /* reset timeout */
216 #define UHCI_CTRL_TIMEOUT 500   /* control transaction timeout */
217 #define UHCI_ISO_DELAY 50       /* delay of start of iso */
218
219 #define UHCI_CURFRAME(sc) (UREAD2(sc, UHCI_FRNUM) & UHCI_FRNUM_MASK)
220
221 #define UHCI_INTR_ENDPT 1
222
223 struct usbd_methods uhci_root_ctrl_methods = {  
224         uhci_root_ctrl_transfer,
225         uhci_root_ctrl_abort,
226         uhci_root_ctrl_close,
227         0,
228 };
229
230 struct usbd_methods uhci_root_intr_methods = {  
231         uhci_root_intr_transfer,
232         uhci_root_intr_abort,
233         uhci_root_intr_close,
234         0,
235 };
236
237 struct usbd_methods uhci_device_ctrl_methods = {
238         uhci_device_ctrl_transfer,
239         uhci_device_ctrl_abort,
240         uhci_device_ctrl_close,
241         0,
242 };
243
244 struct usbd_methods uhci_device_intr_methods = {
245         uhci_device_intr_transfer,
246         uhci_device_intr_abort,
247         uhci_device_intr_close,
248         0,
249 };
250
251 struct usbd_methods uhci_device_bulk_methods = {
252         uhci_device_bulk_transfer,
253         uhci_device_bulk_abort,
254         uhci_device_bulk_close,
255         0,
256 };
257
258 void
259 uhci_busreset(sc)
260         uhci_softc_t *sc;
261 {
262         UHCICMD(sc, UHCI_CMD_GRESET);   /* global reset */
263         usbd_delay_ms(&sc->sc_bus, USB_RESET_DELAY); /* wait at least 10ms */
264         UHCICMD(sc, 0);                 /* do nothing */
265 }
266
267 usbd_status
268 uhci_init(sc)
269         uhci_softc_t *sc;
270 {
271         usbd_status r;
272         int i, j;
273         uhci_soft_qh_t *csqh, *bsqh, *sqh;
274         uhci_soft_td_t *std;
275         usb_dma_t dma;
276         static int uhci_global_init_done = 0;
277
278         DPRINTFN(1,("uhci_init: start\n"));
279
280         if (!uhci_global_init_done) {
281                 uhci_global_init_done = 1;
282                 LIST_INIT(&uhci_ii_free);
283         }
284
285 #if defined(USB_DEBUG)
286         if (uhcidebug > 2)
287                 uhci_dumpregs(sc);
288 #endif
289
290         uhci_run(sc, 0);                        /* stop the controller */
291         UWRITE2(sc, UHCI_INTR, 0);              /* disable interrupts */
292
293         /* Allocate and initialize real frame array. */
294         r = usb_allocmem(sc->sc_dmatag, 
295                          UHCI_FRAMELIST_COUNT * sizeof(uhci_physaddr_t),
296                          UHCI_FRAMELIST_ALIGN, &dma);
297         if (r != USBD_NORMAL_COMPLETION)
298                 return (r);
299         sc->sc_pframes = KERNADDR(&dma);
300         UWRITE2(sc, UHCI_FRNUM, 0);             /* set frame number to 0 */
301         UWRITE4(sc, UHCI_FLBASEADDR, DMAADDR(&dma)); /* set frame list */
302
303         uhci_busreset(sc);
304
305         /* Allocate the dummy QH where bulk traffic will be queued. */
306         bsqh = uhci_alloc_sqh(sc);
307         if (!bsqh)
308                 return (USBD_NOMEM);
309         bsqh->qh->qh_hlink = UHCI_PTR_T;        /* end of QH chain */
310         bsqh->qh->qh_elink = UHCI_PTR_T;
311         sc->sc_bulk_start = sc->sc_bulk_end = bsqh;
312
313         /* Allocate the dummy QH where control traffic will be queued. */
314         csqh = uhci_alloc_sqh(sc);
315         if (!csqh)
316                 return (USBD_NOMEM);
317         csqh->qh->hlink = bsqh;
318         csqh->qh->qh_hlink = bsqh->physaddr | UHCI_PTR_Q;
319         csqh->qh->qh_elink = UHCI_PTR_T;
320         sc->sc_ctl_start = sc->sc_ctl_end = csqh;
321
322         /* 
323          * Make all (virtual) frame list pointers point to the interrupt
324          * queue heads and the interrupt queue heads at the control
325          * queue head and point the physical frame list to the virtual.
326          */
327         for(i = 0; i < UHCI_VFRAMELIST_COUNT; i++) {
328                 std = uhci_alloc_std(sc);
329                 sqh = uhci_alloc_sqh(sc);
330                 if (!std || !sqh)
331                         return (USBD_NOMEM);
332                 std->td->link.sqh = sqh;
333                 std->td->td_link = sqh->physaddr | UHCI_PTR_Q;
334                 std->td->td_status = UHCI_TD_IOS;       /* iso, inactive */
335                 std->td->td_token = 0;
336                 std->td->td_buffer = 0;
337                 sqh->qh->hlink = csqh;
338                 sqh->qh->qh_hlink = csqh->physaddr | UHCI_PTR_Q;
339                 sqh->qh->elink = 0;
340                 sqh->qh->qh_elink = UHCI_PTR_T;
341                 sc->sc_vframes[i].htd = std;
342                 sc->sc_vframes[i].etd = std;
343                 sc->sc_vframes[i].hqh = sqh;
344                 sc->sc_vframes[i].eqh = sqh;
345                 for (j = i; 
346                      j < UHCI_FRAMELIST_COUNT; 
347                      j += UHCI_VFRAMELIST_COUNT)
348                         sc->sc_pframes[j] = std->physaddr;
349         }
350
351         LIST_INIT(&sc->sc_intrhead);
352
353         /* Set up the bus struct. */
354         sc->sc_bus.open_pipe = uhci_open;
355         sc->sc_bus.pipe_size = sizeof(struct uhci_pipe);
356         sc->sc_bus.do_poll = uhci_poll;
357
358         DPRINTFN(1,("uhci_init: enabling\n"));
359         UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE | UHCI_INTR_RIE | 
360                 UHCI_INTR_IOCE | UHCI_INTR_SPIE);       /* enable interrupts */
361
362         uhci_run(sc, 1);                        /* and here we go... */
363         return (USBD_NORMAL_COMPLETION);
364 }
365
366 #ifdef USB_DEBUG
367 static void
368 uhci_dumpregs(sc)
369         uhci_softc_t *sc;
370 {
371         DEVICE_MSG(sc->sc_bus.bdev,("regs: cmd=%04x, sts=%04x, intr=%04x, frnum=%04x, flbase=%08x, sof=%04x, portsc1=%04x, portsc2=%04x\n",
372                UREAD2(sc, UHCI_CMD),
373                UREAD2(sc, UHCI_STS),
374                UREAD2(sc, UHCI_INTR),
375                UREAD2(sc, UHCI_FRNUM),
376                UREAD2(sc, UHCI_FLBASEADDR),
377                UREAD2(sc, UHCI_SOF),
378                UREAD2(sc, UHCI_PORTSC1),
379                UREAD2(sc, UHCI_PORTSC2)));
380 }
381
382 int uhci_longtd = 1;
383
384 void
385 uhci_dump_td(p)
386         uhci_soft_td_t *p;
387 {
388         printf("TD(%p) at %08lx = 0x%08lx 0x%08lx 0x%08lx 0x%08lx\n",
389                p, (long)p->physaddr,
390                (long)p->td->td_link,
391                (long)p->td->td_status,
392                (long)p->td->td_token,
393                (long)p->td->td_buffer);
394         if (uhci_longtd)
395 #if defined(__NetBSD__)
396                 printf("  %b %b,errcnt=%d,actlen=%d pid=%02x,addr=%d,endpt=%d,D=%d,maxlen=%d\n",
397                        (long)p->td->td_link,
398                        "\20\1T\2Q\3VF",
399                        (long)p->td->td_status,
400                        "\20\22BITSTUFF\23CRCTO\24NAK\25BABBLE\26DBUFFER\27STALLED\30ACTIVE\31IOC\32ISO\33LS\36SPD",
401                        UHCI_TD_GET_ERRCNT(p->td->td_status),
402                        UHCI_TD_GET_ACTLEN(p->td->td_status),
403                        UHCI_TD_GET_PID(p->td->td_token),
404                        UHCI_TD_GET_DEVADDR(p->td->td_token),
405                        UHCI_TD_GET_ENDPT(p->td->td_token),
406                        UHCI_TD_GET_DT(p->td->td_token),
407                        UHCI_TD_GET_MAXLEN(p->td->td_token));
408 #elif defined(__FreeBSD__)
409                 printf("  Link=0x%08lx,Status=0x%08lx\n  errcnt=%d,actlen=%d,pid=%02x,addr=%d,endpt=%d,D=%d,maxlen=%d\n", 
410                         (long)p->td->td_link,
411                         (long)p->td->td_status,
412                        UHCI_TD_GET_ERRCNT(p->td->td_status),
413                        UHCI_TD_GET_ACTLEN(p->td->td_status),
414                        UHCI_TD_GET_PID(p->td->td_token),
415                        UHCI_TD_GET_DEVADDR(p->td->td_token),
416                        UHCI_TD_GET_ENDPT(p->td->td_token),
417                        UHCI_TD_GET_DT(p->td->td_token),
418                        UHCI_TD_GET_MAXLEN(p->td->td_token));
419 #endif
420                        
421 }
422
423 void
424 uhci_dump_qh(p)
425         uhci_soft_qh_t *p;
426 {
427         printf("QH(%p) at %08x: hlink=%08x elink=%08x\n", p, (int)p->physaddr,
428                p->qh->qh_hlink, p->qh->qh_elink);
429 }
430
431
432 #if 0
433 void
434 uhci_dump()
435 {
436         uhci_softc_t *sc = uhci;
437
438         uhci_dumpregs(sc);
439         printf("intrs=%d\n", sc->sc_intrs);
440         printf("framelist[i].link = %08x\n", sc->sc_framelist[0].link);
441         uhci_dump_qh(sc->sc_ctl_start->qh->hlink);
442 }
443 #endif
444
445 void
446 uhci_dump_tds(std)
447         uhci_soft_td_t *std;
448 {
449         uhci_soft_td_t *p;
450
451         for(p = std; p; p = p->td->link.std)
452                 uhci_dump_td(p);
453 }
454 #endif
455
456 /*
457  * This routine is executed periodically and simulates interrupts
458  * from the root controller interrupt pipe for port status change.
459  */
460 void
461 uhci_timo(addr)
462         void *addr;
463 {
464         usbd_request_handle reqh = addr;
465         usbd_pipe_handle pipe = reqh->pipe;
466         uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus;
467         struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
468         int s;
469         u_char *p;
470
471         DPRINTFN(15, ("uhci_timo\n"));
472
473         p = KERNADDR(&upipe->u.intr.datadma);
474         p[0] = 0;
475         if (UREAD2(sc, UHCI_PORTSC1) & (UHCI_PORTSC_CSC|UHCI_PORTSC_OCIC))
476                 p[0] |= 1<<1;
477         if (UREAD2(sc, UHCI_PORTSC2) & (UHCI_PORTSC_CSC|UHCI_PORTSC_OCIC))
478                 p[0] |= 1<<2;
479         if (p[0] != 0) {
480                 reqh->actlen = 1;
481                 reqh->status = USBD_NORMAL_COMPLETION;
482                 s = splusb();
483                 reqh->xfercb(reqh);
484                 splx(s);
485         }
486         if (reqh->pipe->intrreqh == reqh) {
487 #if defined(__NetBSD__)
488                 timeout(uhci_timo, reqh, sc->sc_ival);
489 #elif defined(__FreeBSD__)
490                 /* To avoid race conditions we first initialise the struct
491                  * before we use it. The timeout might happen between the
492                  * setting of the timeout and the setting of callout_handler
493                  */
494                 callout_handle_init(&reqh->callout_handler);
495                 reqh->callout_handler = timeout(uhci_timo, reqh, sc->sc_ival);
496 #endif
497         } else {
498                 usb_freemem(sc->sc_dmatag, &upipe->u.intr.datadma);
499         }
500 }
501
502
503 void
504 uhci_lock_frames(sc)
505         uhci_softc_t *sc;
506 {
507         int s = splusb();
508         while (sc->sc_vflock) {
509                 sc->sc_vflock |= UHCI_WANT_LOCK;
510                 tsleep(&sc->sc_vflock, PRIBIO, "uhcqhl", 0);
511         }
512         sc->sc_vflock = UHCI_HAS_LOCK;
513         splx(s);
514 }
515
516 void
517 uhci_unlock_frames(sc)
518         uhci_softc_t *sc;
519 {
520         int s = splusb();
521         sc->sc_vflock &= ~UHCI_HAS_LOCK;
522         if (sc->sc_vflock & UHCI_WANT_LOCK)
523                 wakeup(&sc->sc_vflock);
524         splx(s);
525 }
526
527 /*
528  * Allocate an interrupt information struct.  A free list is kept
529  * for fast allocation.
530  */
531 uhci_intr_info_t *
532 uhci_alloc_intr_info(sc)
533         uhci_softc_t *sc;
534 {
535         uhci_intr_info_t *ii;
536
537         ii = LIST_FIRST(&uhci_ii_free);
538         if (ii)
539                 LIST_REMOVE(ii, list);
540         else {
541                 ii = malloc(sizeof(uhci_intr_info_t), M_USBDEV, M_NOWAIT);
542         }
543         ii->sc = sc;
544         return ii;
545 }
546
547 void
548 uhci_free_intr_info(ii)
549         uhci_intr_info_t *ii;
550 {
551         LIST_INSERT_HEAD(&uhci_ii_free, ii, list); /* and put on free list */
552 }
553
554 /* Add control QH, called at splusb(). */
555 void
556 uhci_add_ctrl(sc, sqh)
557         uhci_softc_t *sc;
558         uhci_soft_qh_t *sqh;
559 {
560         uhci_qh_t *eqh;
561
562         DPRINTFN(10, ("uhci_add_ctrl: sqh=%p\n", sqh));
563         eqh = sc->sc_ctl_end->qh;
564         sqh->qh->hlink     = eqh->hlink;
565         sqh->qh->qh_hlink  = eqh->qh_hlink;
566         eqh->hlink         = sqh;
567         eqh->qh_hlink      = sqh->physaddr | UHCI_PTR_Q;
568         sc->sc_ctl_end = sqh;
569 }
570
571 /* Remove control QH, called at splusb(). */
572 void
573 uhci_remove_ctrl(sc, sqh)
574         uhci_softc_t *sc;
575         uhci_soft_qh_t *sqh;
576 {
577         uhci_soft_qh_t *pqh;
578
579         DPRINTFN(10, ("uhci_remove_ctrl: sqh=%p\n", sqh));
580         for (pqh = sc->sc_ctl_start; pqh->qh->hlink != sqh; pqh=pqh->qh->hlink)
581 #if defined(DIAGNOSTIC) || defined(USB_DEBUG)           
582                 if (pqh->qh->qh_hlink & UHCI_PTR_T) {
583                         printf("uhci_remove_ctrl: QH not found\n");
584                         return;
585                 }
586 #else
587                 ;
588 #endif
589         pqh->qh->hlink    = sqh->qh->hlink;
590         pqh->qh->qh_hlink = sqh->qh->qh_hlink;
591         if (sc->sc_ctl_end == sqh)
592                 sc->sc_ctl_end = pqh;
593 }
594
595 /* Add bulk QH, called at splusb(). */
596 void
597 uhci_add_bulk(sc, sqh)
598         uhci_softc_t *sc;
599         uhci_soft_qh_t *sqh;
600 {
601         uhci_qh_t *eqh;
602
603         DPRINTFN(10, ("uhci_add_bulk: sqh=%p\n", sqh));
604         eqh = sc->sc_bulk_end->qh;
605         sqh->qh->hlink     = eqh->hlink;
606         sqh->qh->qh_hlink  = eqh->qh_hlink;
607         eqh->hlink         = sqh;
608         eqh->qh_hlink      = sqh->physaddr | UHCI_PTR_Q;
609         sc->sc_bulk_end = sqh;
610 }
611
612 /* Remove bulk QH, called at splusb(). */
613 void
614 uhci_remove_bulk(sc, sqh)
615         uhci_softc_t *sc;
616         uhci_soft_qh_t *sqh;
617 {
618         uhci_soft_qh_t *pqh;
619
620         DPRINTFN(10, ("uhci_remove_bulk: sqh=%p\n", sqh));
621         for (pqh = sc->sc_bulk_start; pqh->qh->hlink != sqh; pqh=pqh->qh->hlink)
622 #if defined(DIAGNOSTIC) || defined(USB_DEBUG)           
623                 if (pqh->qh->qh_hlink & UHCI_PTR_T) {
624                         printf("uhci_remove_bulk: QH not found\n");
625                         return;
626                 }
627 #else
628                 ;
629 #endif
630         pqh->qh->hlink    = sqh->qh->hlink;
631         pqh->qh->qh_hlink = sqh->qh->qh_hlink;
632         if (sc->sc_bulk_end == sqh)
633                 sc->sc_bulk_end = pqh;
634 }
635
636 int
637 uhci_intr(p)
638         void *p;
639 {
640         uhci_softc_t *sc = p;
641         int status, ret;
642         uhci_intr_info_t *ii;
643
644         sc->sc_intrs++;
645 #if defined(USB_DEBUG)
646         if (uhcidebug > 9)
647                 uhci_dumpregs(sc);
648 #endif
649         status = UREAD2(sc, UHCI_STS);
650         ret = 0;
651         if (status & UHCI_STS_USBINT) {
652                 UWRITE2(sc, UHCI_STS, UHCI_STS_USBINT); /* acknowledge */
653                 ret = 1;
654         }
655         if (status & UHCI_STS_USBEI) {
656                 UWRITE2(sc, UHCI_STS, UHCI_STS_USBEI); /* acknowledge */
657                 ret = 1;
658         }
659         if (status & UHCI_STS_RD) {
660                 UWRITE2(sc, UHCI_STS, UHCI_STS_RD); /* acknowledge */
661                 DEVICE_MSG(sc->sc_bus.bdev, ("resume detect\n"));
662                 ret = 1;
663         }
664         if (status & UHCI_STS_HSE) {
665                 UWRITE2(sc, UHCI_STS, UHCI_STS_HSE); /* acknowledge */
666                 DEVICE_MSG(sc->sc_bus.bdev, ("Host System Error\n"));
667                 ret = 1;
668         }
669         if (status & UHCI_STS_HCPE) {
670                 UWRITE2(sc, UHCI_STS, UHCI_STS_HCPE); /* acknowledge */
671                 DEVICE_MSG(sc->sc_bus.bdev, ("Host System Error\n"));
672                 ret = 1;
673         }
674         if (status & UHCI_STS_HCH)
675                 DEVICE_ERROR(sc->sc_bus.bdev, ("controller halted\n"));
676         if (!ret)
677                 return 0;
678
679         /*
680          * Interrupts on UHCI really suck.  When the host controller
681          * interrupts because a transfer is completed there is no
682          * way of knowing which transfer it was.  You can scan down
683          * the TDs and QHs of the previous frame to limit the search,
684          * but that assumes that the interrupt was not delayed by more
685          * than 1 ms, which may not always be true (e.g. after debug
686          * output on a slow console).
687          * We scan all interrupt descriptors to see if any have
688          * completed.
689          */
690         for (ii = LIST_FIRST(&sc->sc_intrhead); ii; ii = LIST_NEXT(ii, list))
691                 uhci_check_intr(sc, ii);
692
693         DPRINTFN(10, ("uhci_intr: exit\n"));
694         return 1;
695 }
696
697 /* Check for an interrupt. */
698 void
699 uhci_check_intr(sc, ii)
700         uhci_softc_t *sc;
701         uhci_intr_info_t *ii;
702 {
703         struct uhci_pipe *upipe;
704         uhci_soft_td_t *std, *lstd;
705
706         DPRINTFN(15, ("uhci_check_intr: ii=%p\n", ii));
707 #ifdef DIAGNOSTIC
708         if (!ii) {
709                 printf("uhci_check_intr: no ii? %p\n", ii);
710                 return;
711         }
712 #endif
713         if (!ii->stdstart)
714                 return;
715         lstd = ii->stdend;
716 #ifdef DIAGNOSTIC
717         if (!lstd) {
718                 printf("uhci_check_intr: std==0\n");
719                 return;
720         }
721 #endif
722         /* If the last TD is still active the whole transfer probably is. */
723         if (lstd->td->td_status & UHCI_TD_ACTIVE) {
724                 DPRINTFN(15, ("uhci_check_intr: active ii=%p\n", ii));
725                 for (std = ii->stdstart; std != lstd; std = std->td->link.std)
726                         if (std->td->td_status & UHCI_TD_STALLED)
727                                 goto done;
728                 DPRINTFN(15, ("uhci_check_intr: ii=%p still active\n", ii));
729                 return;
730         }
731  done:
732         upipe = (struct uhci_pipe *)ii->reqh->pipe;
733         upipe->pipe.endpoint->toggle = upipe->newtoggle;
734         uhci_ii_done(ii, 0);
735 #if defined(__NetBSD__)
736         untimeout(uhci_timeout, ii);
737 #elif defined(__FreeBSD__)
738         untimeout(uhci_timeout, ii, ii->callout_handler);
739 #endif
740 }
741
742 void
743 uhci_ii_done(ii, timo)
744         uhci_intr_info_t *ii;
745         int timo;
746 {
747         usbd_request_handle reqh = ii->reqh;
748         uhci_soft_td_t *std;
749         u_int32_t tst;
750         int len, status;
751
752         DPRINTFN(10, ("uhci_ii_done: ii=%p ready %d\n", ii, timo));
753
754 #ifdef DIAGNOSTIC
755         {
756                 int s = splhigh();
757                 if (ii->isdone) {
758                         printf("uhci_ii_done: is done!\n");
759                         splx(s);
760                         return;
761                 }
762                 ii->isdone = 1;
763                 splx(s);
764         }
765 #endif
766
767         /* The transfer is done, compute length and status. */
768         for (len = status = 0, std = ii->stdstart; 
769              std != 0; 
770              std = std->td->link.std) {
771                 tst = std->td->td_status;
772                 status |= tst;
773 #ifdef USB_DEBUG
774                 if ((tst & UHCI_TD_ERROR) && uhcidebug) {
775                         printf("uhci_ii_done: intr error TD:\n");
776                         uhci_dump_td(std);
777                 }
778 #endif
779                 if (UHCI_TD_GET_PID(std->td->td_token) != UHCI_TD_PID_SETUP)
780                         len += UHCI_TD_GET_ACTLEN(tst);
781         }
782         status &= UHCI_TD_ERROR;
783         /* NWH wrong func name also below, 'uhci_intr' 3 times
784         DPRINTFN(10, ("uhci_check_intr: len=%d, status=0x%x\n", len, status));
785          */
786         DPRINTFN(10, ("uhci_ii_done: len=%d\n", len));
787         if (status != 0) {
788 #if defined(__NetBSD__)
789                 DPRINTFN(-1+(status==UHCI_TD_STALLED),
790                          ("uhci_ii_done: error, status 0x%b\n", (long)status, 
791                           "\20\22BITSTUFF\23CRCTO\24NAK\25BABBLE\26DBUFFER\27STALLED\30ACTIVE"));
792 #elif defined(__FreeBSD__)
793                 DPRINTFN(-1+(status==UHCI_TD_STALLED),
794                         ("uhci_ii_done: error, status 0x%08lx\n", (long)status));
795 #endif
796                 if (status == UHCI_TD_STALLED)
797                         reqh->status = USBD_STALLED;
798                 else
799                         reqh->status = USBD_IOERROR; /* more info XXX */
800                 reqh->actlen = 0;
801         } else {
802                 reqh->status = USBD_NORMAL_COMPLETION;
803                 reqh->actlen = len;
804         }
805         if (timo) {
806                 /* We got a timeout.  Make sure transaction is not active. */
807                 reqh->status = USBD_TIMEOUT;
808                 for (std = ii->stdstart; std != 0; std = std->td->link.std)
809                         std->td->td_status &= ~UHCI_TD_ACTIVE;
810                 /* XXX should we wait 1 ms */
811         }
812         DPRINTFN(5, ("uhci_ii_done: calling handler ii=%p\n", ii));
813
814         switch (reqh->pipe->endpoint->edesc->bmAttributes & UE_XFERTYPE) {
815         case UE_CONTROL:
816                 uhci_ctrl_done(ii);
817                 break;
818         case UE_ISOCHRONOUS:
819                 printf("uhci_ii_done: ISO??\n");
820                 break;
821         case UE_BULK:
822                 uhci_bulk_done(ii);
823                 break;
824         case UE_INTERRUPT:
825                 uhci_intr_done(ii);
826                 break;
827         }
828
829         /* And finally execute callback. */
830         reqh->xfercb(reqh);
831 }
832
833 void
834 uhci_timeout(addr)
835         void *addr;
836 {
837         uhci_intr_info_t *ii = addr;
838         int s;
839
840         DPRINTF(("uhci_timeout: ii=%p\n", ii));
841         s = splusb();
842         uhci_ii_done(ii, 1);
843         splx(s);
844 }
845
846 /*
847  * Wait here until controller claims to have an interrupt.
848  * Then call uhci_intr and return.  Use timeout to avoid waiting
849  * too long.
850  */
851 void
852 uhci_waitintr(sc, reqh)
853         uhci_softc_t *sc;
854         usbd_request_handle reqh;
855 {
856         int timo = reqh->timeout;
857         int usecs;
858         int hzs;
859
860         DPRINTFN(10,("uhci_waitintr: timout = %ds\n", timo));
861
862         reqh->status = USBD_IN_PROGRESS;
863         for (usecs = timo * 1000000 / hz; usecs > 0; usecs -= 100000) {
864                 /* NWH replaced by usbd_delay_ms
865                 delay(1000);
866                    NWH and descreased frequency from 1ms to 100ms, see also usecs -=...
867                  */
868                 usbd_delay_ms(&(sc->sc_bus), 100);
869                 /* NWH disabled 
870                 DPRINTFN(10,("uhci_waitintr: 0x%04x\n", UREAD2(sc, UHCI_STS)));
871                  */
872                 if (UREAD2(sc, UHCI_STS) & UHCI_STS_USBINT) {
873                         uhci_intr(sc);
874                         if (reqh->status != USBD_IN_PROGRESS)
875                                 return;
876                 }
877         }
878         reqh->status = USBD_TIMEOUT;
879         reqh->xfercb(reqh);
880 }
881
882 void
883 uhci_poll(bus)
884         struct usbd_bus *bus;
885 {
886         uhci_softc_t *sc = (uhci_softc_t *)bus;
887
888         if (UREAD2(sc, UHCI_STS) & UHCI_STS_USBINT)
889                 uhci_intr(sc);
890 }
891
892 #if 0
893 void
894 uhci_reset(p)
895         void *p;
896 {
897         uhci_softc_t *sc = p;
898         int n;
899
900         UHCICMD(sc, UHCI_CMD_HCRESET);
901         /* The reset bit goes low when the controller is done. */
902         for (n = 0; n < UHCI_RESET_TIMEOUT && 
903                     (UREAD2(sc, UHCI_CMD) & UHCI_CMD_HCRESET); n++)
904                 delay(100);
905         if (n >= UHCI_RESET_TIMEOUT)
906                 DEVICE_ERROR(sc->sc_bus.bdev, ("controller did not reset\n"));
907 }
908 #endif
909
910 void
911 uhci_run(sc, run)
912         uhci_softc_t *sc;
913         int run;
914 {
915         int s, n, running;
916
917         run = run != 0;
918         s = splusb();           /* XXX really? */
919         running = !(UREAD2(sc, UHCI_STS) & UHCI_STS_HCH);
920         if (run == running) {
921                 splx(s);
922                 return;
923         }
924         UWRITE2(sc, UHCI_CMD, run ? UHCI_CMD_RS : 0);
925         for(n = 0; n < 100; n++) {
926                 running = !(UREAD2(sc, UHCI_STS) & UHCI_STS_HCH);
927                 /* return when we've entered the state we want */
928                 if (run == running) {
929                         splx(s);
930                         return;
931                 }
932         }
933         splx(s);
934         DEVICE_ERROR(sc->sc_bus.bdev, ("cannot %s\n", (run ? "start" : "stop")));
935 }
936
937 /*
938  * Memory management routines.
939  *  uhci_alloc_std allocates TDs
940  *  uhci_alloc_sqh allocates QHs
941  * These two routines do their own free list management,
942  * partly for speed, partly because allocating DMAable memory
943  * has page size granularaity so much memory would be wasted if
944  * only one TD/QH (32 bytes) was placed in each alloacted chunk.
945  */
946
947 uhci_soft_td_t *
948 uhci_alloc_std(sc)
949         uhci_softc_t *sc;
950 {
951         uhci_soft_td_t *std;
952         usbd_status r;
953         int i;
954         usb_dma_t dma;
955
956         if (!sc->sc_freetds) {
957                 DPRINTFN(2,("uhci_alloc_std: allocating chunk\n"));
958                 std = malloc(sizeof(uhci_soft_td_t) * UHCI_TD_CHUNK, 
959                              M_USBDEV, M_NOWAIT);
960                 if (!std)
961                         return 0;
962                 r = usb_allocmem(sc->sc_dmatag, UHCI_TD_SIZE * UHCI_TD_CHUNK,
963                                  UHCI_TD_ALIGN, &dma);
964                 if (r != USBD_NORMAL_COMPLETION) {
965                         free(std, M_USBDEV);
966                         return 0;
967                 }
968                 for(i = 0; i < UHCI_TD_CHUNK; i++, std++) {
969                         std->physaddr = DMAADDR(&dma) + 
970                                 i * UHCI_TD_SIZE;
971                         std->td = (uhci_td_t *)
972                                 ((char *)KERNADDR(&dma) + i * UHCI_TD_SIZE);
973                         std->td->link.std = sc->sc_freetds;
974                         sc->sc_freetds = std;
975                 }
976         }
977         std = sc->sc_freetds;
978         sc->sc_freetds = std->td->link.std;
979         memset(std->td, 0, UHCI_TD_SIZE);
980         return std;
981 }
982
983 void
984 uhci_free_std(sc, std)
985         uhci_softc_t *sc;
986         uhci_soft_td_t *std;
987 {
988 #ifdef DIAGNOSTIC
989 #define TD_IS_FREE 0x12345678
990         if (std->td->td_token == TD_IS_FREE) {
991                 printf("uhci_free_std: freeing free TD %p\n", std);
992                 return;
993         }
994         std->td->td_token = TD_IS_FREE;
995 #endif
996         std->td->link.std = sc->sc_freetds;
997         sc->sc_freetds = std;
998 }
999
1000 uhci_soft_qh_t *
1001 uhci_alloc_sqh(sc)
1002         uhci_softc_t *sc;
1003 {
1004         uhci_soft_qh_t *sqh;
1005         usbd_status r;
1006         int i, offs;
1007         usb_dma_t dma;
1008
1009         if (!sc->sc_freeqhs) {
1010                 DPRINTFN(2, ("uhci_alloc_sqh: allocating chunk\n"));
1011                 sqh = malloc(sizeof(uhci_soft_qh_t) * UHCI_QH_CHUNK, 
1012                              M_USBDEV, M_NOWAIT);
1013                 if (!sqh)
1014                         return 0;
1015                 r = usb_allocmem(sc->sc_dmatag, UHCI_QH_SIZE * UHCI_QH_CHUNK,
1016                                  UHCI_QH_ALIGN, &dma);
1017                 if (r != USBD_NORMAL_COMPLETION) {
1018                         free(sqh, M_USBDEV);
1019                         return 0;
1020                 }
1021                 for(i = 0; i < UHCI_QH_CHUNK; i++, sqh++) {
1022                         offs = i * UHCI_QH_SIZE;
1023                         sqh->physaddr = DMAADDR(&dma) + offs;
1024                         sqh->qh = (uhci_qh_t *)
1025                                         ((char *)KERNADDR(&dma) + offs);
1026                         sqh->qh->hlink = sc->sc_freeqhs;
1027                         sc->sc_freeqhs = sqh;
1028                 }
1029         }
1030         sqh = sc->sc_freeqhs;
1031         sc->sc_freeqhs = sqh->qh->hlink;
1032         memset(sqh->qh, 0, UHCI_QH_SIZE);
1033         return sqh;
1034 }
1035
1036 void
1037 uhci_free_sqh(sc, sqh)
1038         uhci_softc_t *sc;
1039         uhci_soft_qh_t *sqh;
1040 {
1041         sqh->qh->hlink = sc->sc_freeqhs;
1042         sc->sc_freeqhs = sqh;
1043 }
1044
1045 /* 
1046  * Enter a list of transfers onto a control queue.
1047  * Called at splusb() 
1048  */
1049 void
1050 uhci_enter_ctl_q(sc, sqh, ii)
1051         uhci_softc_t *sc;
1052         uhci_soft_qh_t *sqh;
1053         uhci_intr_info_t *ii;
1054 {
1055         DPRINTFN(5, ("uhci_enter_ctl_q: sqh=%p\n", sqh));
1056
1057 }
1058
1059 void
1060 uhci_free_std_chain(sc, std, stdend)
1061         uhci_softc_t *sc;
1062         uhci_soft_td_t *std;
1063         uhci_soft_td_t *stdend;
1064 {
1065         uhci_soft_td_t *p;
1066
1067         for (; std != stdend; std = p) {
1068                 p = std->td->link.std;
1069                 uhci_free_std(sc, std);
1070         }
1071 }
1072
1073 usbd_status
1074 uhci_alloc_std_chain(upipe, sc, len, rd, dma, sp, ep)
1075         struct uhci_pipe *upipe;
1076         uhci_softc_t *sc;
1077         int len, rd;
1078         usb_dma_t *dma;
1079         uhci_soft_td_t **sp, **ep;
1080 {
1081         uhci_soft_td_t *p, *lastp;
1082         uhci_physaddr_t lastlink;
1083         u_int32_t ls;
1084         int i, ntd, l, tog, maxp;
1085         int addr = upipe->pipe.device->address;
1086         int endpt = upipe->pipe.endpoint->edesc->bEndpointAddress;
1087
1088         DPRINTFN(15, ("uhci_alloc_std_chain: len=%d\n", len));
1089         if (len == 0) {
1090                 *sp = *ep = 0;
1091                 printf("uhci_alloc_std_chain: len=0\n");
1092                 return (USBD_NORMAL_COMPLETION);
1093         }
1094         ls = upipe->pipe.device->lowspeed ? UHCI_TD_LS : 0;
1095         maxp = UGETW(upipe->pipe.endpoint->edesc->wMaxPacketSize);
1096         if (maxp == 0) {
1097                 printf("uhci_alloc_std_chain: maxp=0\n");
1098                 return (USBD_INVAL);
1099         }
1100         ntd = (len + maxp - 1) / maxp;
1101         tog = upipe->pipe.endpoint->toggle;
1102         if (ntd % 2 == 0)
1103                 tog ^= 1;
1104         upipe->newtoggle = tog ^ 1;
1105         lastp = 0;
1106         lastlink = UHCI_PTR_T;
1107         ntd--;
1108         for (i = ntd; i >= 0; i--) {
1109                 p = uhci_alloc_std(sc);
1110                 if (!p) {
1111                         uhci_free_std_chain(sc, lastp, 0);
1112                         return (USBD_NOMEM);
1113                 }
1114                 p->td->link.std = lastp;
1115                 p->td->td_link = lastlink;
1116                 lastp = p;
1117                 lastlink = p->physaddr;
1118                 p->td->td_status = UHCI_TD_SET_ERRCNT(2) | ls | UHCI_TD_ACTIVE;
1119                 if (i == ntd) {
1120                         /* last TD */
1121                         l = len % maxp;
1122                         if (l == 0) l = maxp;
1123                         *ep = p;
1124                 } else
1125                         l = maxp;
1126                 p->td->td_token = 
1127                     rd ? UHCI_TD_IN (l, endpt, addr, tog) :
1128                          UHCI_TD_OUT(l, endpt, addr, tog);
1129                 p->td->td_buffer = DMAADDR(dma) + i * maxp;
1130                 tog ^= 1;
1131         }
1132         *sp = lastp;
1133         /*upipe->pipe.endpoint->toggle = tog;*/
1134         DPRINTFN(10, ("uhci_alloc_std_chain: oldtog=%d newtog=%d\n", 
1135                       upipe->pipe.endpoint->toggle, upipe->newtoggle));
1136         return (USBD_NORMAL_COMPLETION);
1137 }
1138
1139 usbd_status
1140 uhci_device_bulk_transfer(reqh)
1141         usbd_request_handle reqh;
1142 {
1143         struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe;
1144         usbd_device_handle dev = upipe->pipe.device;
1145         uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
1146         uhci_intr_info_t *ii = upipe->iinfo;
1147         uhci_soft_td_t *xfer, *xferend;
1148         uhci_soft_qh_t *sqh;
1149         usb_dma_t *dmap;
1150         usbd_status r;
1151         int len, isread;
1152         int s;
1153
1154         DPRINTFN(3, ("uhci_device_bulk_transfer: reqh=%p buf=%p len=%d flags=%d\n",
1155                      reqh, reqh->buffer, reqh->length, reqh->flags));
1156
1157         if (reqh->isreq)
1158                 panic("uhci_device_bulk_transfer: a request\n");
1159
1160         len = reqh->length;
1161         dmap = &upipe->u.bulk.datadma;
1162         isread = reqh->pipe->endpoint->edesc->bEndpointAddress & UE_IN;
1163         sqh = upipe->u.bulk.sqh;
1164
1165         upipe->u.bulk.isread = isread;
1166         upipe->u.bulk.length = len;
1167
1168         r = usb_allocmem(sc->sc_dmatag, len, 0, dmap);
1169         if (r != USBD_NORMAL_COMPLETION)
1170                 goto ret1;
1171         r = uhci_alloc_std_chain(upipe, sc, len, isread, 
1172                                  dmap, &xfer, &xferend);
1173         if (r != USBD_NORMAL_COMPLETION)
1174                 goto ret2;
1175         xferend->td->td_status |= UHCI_TD_IOC;
1176
1177         if (!isread && len != 0)
1178                 memcpy(KERNADDR(dmap), reqh->buffer, len);
1179
1180 #ifdef USB_DEBUG
1181         if (uhcidebug > 10) {
1182                 printf("uhci_device_bulk_transfer: xfer(1)\n");
1183                 uhci_dump_tds(xfer);
1184         }
1185 #endif
1186
1187         /* Set up interrupt info. */
1188         ii->reqh = reqh;
1189         ii->stdstart = xfer;
1190         ii->stdend = xferend;
1191 #ifdef DIAGNOSTIC
1192         ii->isdone = 0;
1193 #endif
1194
1195         sqh->qh->elink = xfer;
1196         sqh->qh->qh_elink = xfer->physaddr;
1197         sqh->intr_info = ii;
1198
1199         s = splusb();
1200         uhci_add_bulk(sc, sqh);
1201         LIST_INSERT_HEAD(&sc->sc_intrhead, ii, list);
1202
1203         if (reqh->timeout && !sc->sc_bus.use_polling)
1204                 timeout(uhci_timeout, ii, MS_TO_TICKS(reqh->timeout));
1205         splx(s);
1206
1207 #ifdef USB_DEBUG
1208         if (uhcidebug > 10) {
1209                 printf("uhci_device_bulk_transfer: xfer(2)\n");
1210                 uhci_dump_tds(xfer);
1211         }
1212 #endif
1213
1214         return (USBD_IN_PROGRESS);
1215
1216  ret2:
1217         if (len != 0)
1218                 usb_freemem(sc->sc_dmatag, dmap);
1219  ret1:
1220         return (r);
1221 }
1222
1223 /* Abort a device bulk request. */
1224 void
1225 uhci_device_bulk_abort(reqh)
1226         usbd_request_handle reqh;
1227 {
1228         /* XXX inactivate */
1229         usbd_delay_ms(reqh->pipe->device->bus, 1);      /* make sure it is finished */
1230         /* XXX call done */
1231 }
1232
1233 /* Close a device bulk pipe. */
1234 void
1235 uhci_device_bulk_close(pipe)
1236         usbd_pipe_handle pipe;
1237 {
1238         struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
1239         usbd_device_handle dev = upipe->pipe.device;
1240         uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
1241
1242         uhci_free_sqh(sc, upipe->u.bulk.sqh);
1243         uhci_free_intr_info(upipe->iinfo);
1244         /* XXX free other resources */
1245 }
1246
1247 usbd_status
1248 uhci_device_ctrl_transfer(reqh)
1249         usbd_request_handle reqh;
1250 {
1251         uhci_softc_t *sc = (uhci_softc_t *)reqh->pipe->device->bus;
1252         usbd_status r;
1253
1254         if (!reqh->isreq)
1255                 panic("uhci_device_ctrl_transfer: not a request\n");
1256
1257         r = uhci_device_request(reqh);
1258         if (r != USBD_NORMAL_COMPLETION)
1259                 return (r);
1260
1261         if (sc->sc_bus.use_polling)
1262                 uhci_waitintr(sc, reqh);
1263         return (USBD_IN_PROGRESS);
1264 }
1265
1266 usbd_status
1267 uhci_device_intr_transfer(reqh)
1268         usbd_request_handle reqh;
1269 {
1270         struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe;
1271         usbd_device_handle dev = upipe->pipe.device;
1272         uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
1273         uhci_intr_info_t *ii = upipe->iinfo;
1274         uhci_soft_td_t *xfer, *xferend;
1275         uhci_soft_qh_t *sqh;
1276         usb_dma_t *dmap;
1277         usbd_status r;
1278         int len, i;
1279         int s;
1280
1281         DPRINTFN(3, ("uhci_device_intr_transfer: reqh=%p buf=%p len=%d flags=%d\n",
1282                      reqh, reqh->buffer, reqh->length, reqh->flags));
1283
1284         if (reqh->isreq)
1285                 panic("uhci_device_intr_transfer: a request\n");
1286
1287         len = reqh->length;
1288         dmap = &upipe->u.intr.datadma;
1289         if (len == 0)
1290                 return (USBD_INVAL); /* XXX should it be? */
1291
1292         r = usb_allocmem(sc->sc_dmatag, len, 0, dmap);
1293         if (r != USBD_NORMAL_COMPLETION)
1294                 goto ret1;
1295         r = uhci_alloc_std_chain(upipe, sc, len, 1, dmap, &xfer, &xferend);
1296         if (r != USBD_NORMAL_COMPLETION)
1297                 goto ret2;
1298         xferend->td->td_status |= UHCI_TD_IOC;
1299
1300 #ifdef USB_DEBUG
1301         if (uhcidebug > 10) {
1302                 printf("uhci_device_intr_transfer: xfer(1)\n");
1303                 uhci_dump_tds(xfer);
1304                 uhci_dump_qh(upipe->u.intr.qhs[0]);
1305         }
1306 #endif
1307
1308         s = splusb();
1309         /* Set up interrupt info. */
1310         ii->reqh = reqh;
1311         ii->stdstart = xfer;
1312         ii->stdend = xferend;
1313 #ifdef DIAGNOSTIC
1314         ii->isdone = 0;
1315 #endif
1316
1317 DPRINTFN(10,("uhci_device_intr_transfer: qhs[0]=%p\n", upipe->u.intr.qhs[0]));
1318         for (i = 0; i < upipe->u.intr.npoll; i++) {
1319                 sqh = upipe->u.intr.qhs[i];
1320                 sqh->qh->elink = xfer;
1321                 sqh->qh->qh_elink = xfer->physaddr;
1322         }
1323         splx(s);
1324
1325 #ifdef USB_DEBUG
1326         if (uhcidebug > 10) {
1327                 printf("uhci_device_intr_transfer: xfer(2)\n");
1328                 uhci_dump_tds(xfer);
1329                 uhci_dump_qh(upipe->u.intr.qhs[0]);
1330         }
1331 #endif
1332
1333         return (USBD_IN_PROGRESS);
1334
1335  ret2:
1336         if (len != 0)
1337                 usb_freemem(sc->sc_dmatag, dmap);
1338  ret1:
1339         return (r);
1340 }
1341
1342 /* Abort a device control request. */
1343 void
1344 uhci_device_ctrl_abort(reqh)
1345         usbd_request_handle reqh;
1346 {
1347         /* XXX inactivate */
1348         usbd_delay_ms(reqh->pipe->device->bus, 1);      /* make sure it is finished */
1349         /* XXX call done */
1350 }
1351
1352 /* Close a device control pipe. */
1353 void
1354 uhci_device_ctrl_close(pipe)
1355         usbd_pipe_handle pipe;
1356 {
1357         struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
1358
1359         uhci_free_intr_info(upipe->iinfo);
1360         /* XXX free other resources */
1361 }
1362
1363 /* Abort a device interrupt request. */
1364 void
1365 uhci_device_intr_abort(reqh)
1366         usbd_request_handle reqh;
1367 {
1368         struct uhci_pipe *upipe;
1369
1370         DPRINTFN(1, ("uhci_device_intr_abort: reqh=%p\n", reqh));
1371         /* XXX inactivate */
1372         usbd_delay_ms(reqh->pipe->device->bus, 2);      /* make sure it is finished */
1373         if (reqh->pipe->intrreqh == reqh) {
1374                 DPRINTF(("uhci_device_intr_abort: remove\n"));
1375                 reqh->pipe->intrreqh = 0;
1376                 upipe = (struct uhci_pipe *)reqh->pipe;
1377                 uhci_intr_done(upipe->u.intr.qhs[0]->intr_info);
1378         }
1379 }
1380
1381 /* Close a device interrupt pipe. */
1382 void
1383 uhci_device_intr_close(pipe)
1384         usbd_pipe_handle pipe;
1385 {
1386         struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
1387         uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus;
1388         int i, s, npoll;
1389
1390         upipe->iinfo->stdstart = 0;             /* inactive */
1391
1392         /* Unlink descriptors from controller data structures. */
1393         npoll = upipe->u.intr.npoll;
1394         uhci_lock_frames(sc);
1395         for (i = 0; i < npoll; i++)
1396                 uhci_remove_intr(sc, upipe->u.intr.qhs[i]->pos, 
1397                                  upipe->u.intr.qhs[i]);
1398         uhci_unlock_frames(sc);
1399
1400         /* 
1401          * We now have to wait for any activity on the physical
1402          * descriptors to stop.
1403          */
1404         usbd_delay_ms(&sc->sc_bus, 2);
1405
1406         for(i = 0; i < npoll; i++)
1407                 uhci_free_sqh(sc, upipe->u.intr.qhs[i]);
1408         free(upipe->u.intr.qhs, M_USB);
1409
1410         s = splusb();
1411         LIST_REMOVE(upipe->iinfo, list);        /* remove from active list */
1412         splx(s);
1413         uhci_free_intr_info(upipe->iinfo);
1414
1415         /* XXX free other resources */
1416 }
1417
1418 usbd_status
1419 uhci_device_request(reqh)
1420         usbd_request_handle reqh;
1421 {
1422         struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe;
1423         usb_device_request_t *req = &reqh->request;
1424         usbd_device_handle dev = upipe->pipe.device;
1425         uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
1426         int addr = dev->address;
1427         int endpt = upipe->pipe.endpoint->edesc->bEndpointAddress;
1428         uhci_intr_info_t *ii = upipe->iinfo;
1429         uhci_soft_td_t *setup, *xfer, *stat, *next, *xferend;
1430         uhci_soft_qh_t *sqh;
1431         usb_dma_t *dmap;
1432         int len;
1433         u_int32_t ls;
1434         usbd_status r;
1435         int isread;
1436         int s;
1437
1438         DPRINTFN(1,("uhci_device_control type=0x%02x, request=0x%02x, wValue=0x%04x, wIndex=0x%04x len=%d, addr=%d, endpt=%d\n",
1439                     req->bmRequestType, req->bRequest, UGETW(req->wValue),
1440                     UGETW(req->wIndex), UGETW(req->wLength),
1441                     addr, endpt));
1442
1443         ls = dev->lowspeed ? UHCI_TD_LS : 0;
1444         isread = req->bmRequestType & UT_READ;
1445         len = UGETW(req->wLength);
1446
1447         setup = upipe->u.ctl.setup;
1448         stat = upipe->u.ctl.stat;
1449         sqh = upipe->u.ctl.sqh;
1450         dmap = &upipe->u.ctl.datadma;
1451
1452         /* Set up data transaction */
1453         if (len != 0) {
1454                 r = usb_allocmem(sc->sc_dmatag, len, 0, dmap);
1455                 if (r != USBD_NORMAL_COMPLETION)
1456                         goto ret1;
1457                 upipe->pipe.endpoint->toggle = 1;
1458                 r = uhci_alloc_std_chain(upipe, sc, len, isread, 
1459                                          dmap, &xfer, &xferend);
1460                 if (r != USBD_NORMAL_COMPLETION)
1461                         goto ret2;
1462                 next = xfer;
1463                 xferend->td->link.std = stat;
1464                 xferend->td->td_link = stat->physaddr;
1465         } else {
1466                 xfer = 0;
1467                 next = stat;
1468         }
1469         upipe->u.ctl.length = len;
1470         upipe->u.ctl.xferend = xferend;
1471
1472         memcpy(KERNADDR(&upipe->u.ctl.reqdma), req, sizeof *req);
1473         if (!isread && len != 0)
1474                 memcpy(KERNADDR(dmap), reqh->buffer, len);
1475
1476         setup->td->link.std = next;
1477         setup->td->td_link = next->physaddr;
1478         setup->td->td_status = UHCI_TD_SET_ERRCNT(2) | ls | UHCI_TD_ACTIVE;
1479         setup->td->td_token = UHCI_TD_SETUP(sizeof *req, endpt, addr);
1480         setup->td->td_buffer = DMAADDR(&upipe->u.ctl.reqdma);
1481
1482         stat->td->link.std = 0;
1483         stat->td->td_link = UHCI_PTR_T;
1484         stat->td->td_status = UHCI_TD_SET_ERRCNT(2) | ls | 
1485                 UHCI_TD_ACTIVE | UHCI_TD_IOC;
1486         stat->td->td_token = 
1487                 isread ? UHCI_TD_OUT(0, endpt, addr, 1) :
1488                          UHCI_TD_IN (0, endpt, addr, 1);
1489         stat->td->td_buffer = 0;
1490
1491 #ifdef USB_DEBUG
1492         if (uhcidebug > 20) {
1493                 printf("uhci_device_request: setup\n");
1494                 uhci_dump_td(setup);
1495                 printf("uhci_device_request: stat\n");
1496                 uhci_dump_td(stat);
1497         }
1498 #endif
1499
1500         /* Set up interrupt info. */
1501         ii->reqh = reqh;
1502         ii->stdstart = setup;
1503         ii->stdend = stat;
1504 #ifdef DIAGNOSTIC
1505         ii->isdone = 0;
1506 #endif
1507
1508         sqh->qh->elink = setup;
1509         sqh->qh->qh_elink = setup->physaddr;
1510         sqh->intr_info = ii;
1511
1512         s = splusb();
1513         uhci_add_ctrl(sc, sqh);
1514         LIST_INSERT_HEAD(&sc->sc_intrhead, ii, list);
1515 #ifdef USB_DEBUG
1516         if (uhcidebug > 12) {
1517                 uhci_soft_td_t *std;
1518                 uhci_soft_qh_t *xqh;
1519                 uhci_soft_qh_t *sxqh;
1520                 int maxqh = 0;
1521                 uhci_physaddr_t link;
1522                 printf("uhci_enter_ctl_q: follow from [0]\n");
1523                 for (std = sc->sc_vframes[0].htd, link = 0;
1524                      (link & UHCI_PTR_Q) == 0;
1525                      std = std->td->link.std) {
1526                         link = std->td->td_link;
1527                         uhci_dump_td(std);
1528                 }
1529                 for (sxqh = xqh = (uhci_soft_qh_t *)std;
1530                      xqh;
1531                      /* FIXME NWH seems to be a circular list ??
1532                       * checking for beginning of list end of list
1533                       * and printing a maximum of 5 QH's ...
1534                      xqh = xqh->qh->hlink)
1535                         */
1536                      xqh = (maxqh++ == 5 || xqh->qh->hlink==sxqh || xqh->qh->hlink==xqh? NULL : xqh->qh->hlink)) {
1537                         uhci_dump_qh(xqh);
1538                         uhci_dump_qh(sxqh);
1539                 }
1540                 printf("Enqueued QH:\n");
1541                 uhci_dump_qh(sqh);
1542                 uhci_dump_tds(sqh->qh->elink);
1543         }
1544 #endif
1545         if (reqh->timeout && !sc->sc_bus.use_polling)
1546 #if defined(__NetBSD__)
1547                 timeout(uhci_timeout, ii, MS_TO_TICKS(reqh->timeout));
1548 #elif defined(__FreeBSD__)
1549                 /* To avoid race conditions we first initialise the struct
1550                  * before we use it. The timeout may happen between the setting
1551                  * of the timeout and the setting of callout_handle
1552                  */
1553                 callout_handle_init(&ii->callout_handler);
1554                 ii->callout_handler = timeout(uhci_timeout, ii, MS_TO_TICKS(reqh->timeout));
1555 #endif
1556         splx(s);
1557
1558         return (USBD_NORMAL_COMPLETION);
1559
1560  ret2:
1561         if (len != 0)
1562                 usb_freemem(sc->sc_dmatag, dmap);
1563  ret1:
1564         return (r);
1565 }
1566
1567 void
1568 uhci_intr_done(ii)
1569         uhci_intr_info_t *ii;
1570 {
1571         uhci_softc_t *sc = ii->sc;
1572         usbd_request_handle reqh = ii->reqh;
1573         struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe;
1574         usb_dma_t *dma;
1575         uhci_soft_qh_t *sqh;
1576         int i, npoll;
1577
1578         DPRINTFN(5, ("uhci_intr_done: length=%d\n", reqh->actlen));
1579
1580         dma = &upipe->u.intr.datadma;
1581         memcpy(reqh->buffer, KERNADDR(dma), reqh->actlen);
1582         npoll = upipe->u.intr.npoll;
1583         for(i = 0; i < npoll; i++) {
1584                 sqh = upipe->u.intr.qhs[i];
1585                 sqh->qh->elink = 0;
1586                 sqh->qh->qh_elink = UHCI_PTR_T;
1587         }
1588         uhci_free_std_chain(sc, ii->stdstart, 0);
1589
1590         /* XXX Wasteful. */
1591         if (reqh->pipe->intrreqh == reqh) {
1592                 uhci_soft_td_t *xfer, *xferend;
1593
1594                 /* This alloc cannot fail since we freed the chain above. */
1595                 uhci_alloc_std_chain(upipe, sc, reqh->length, 1, dma,
1596                                      &xfer, &xferend);
1597                 xferend->td->td_status |= UHCI_TD_IOC;
1598
1599 #ifdef USB_DEBUG
1600                 if (uhcidebug > 10) {
1601                         printf("uhci_device_intr_done: xfer(1)\n");
1602                         uhci_dump_tds(xfer);
1603                         uhci_dump_qh(upipe->u.intr.qhs[0]);
1604                 }
1605 #endif
1606
1607                 ii->stdstart = xfer;
1608                 ii->stdend = xferend;
1609 #ifdef DIAGNOSTIC
1610                 ii->isdone = 0;
1611 #endif
1612                 for (i = 0; i < npoll; i++) {
1613                         sqh = upipe->u.intr.qhs[i];
1614                         sqh->qh->elink = xfer;
1615                         sqh->qh->qh_elink = xfer->physaddr;
1616                 }
1617         } else {
1618                 usb_freemem(sc->sc_dmatag, dma);
1619                 ii->stdstart = 0;       /* mark as inactive */
1620         }
1621 }
1622
1623 /* Deallocate request data structures */
1624 void
1625 uhci_ctrl_done(ii)
1626         uhci_intr_info_t *ii;
1627 {
1628         uhci_softc_t *sc = ii->sc;
1629         usbd_request_handle reqh = ii->reqh;
1630         struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe;
1631         u_int len = upipe->u.ctl.length;
1632         usb_dma_t *dma;
1633         uhci_td_t *htd = ii->stdstart->td;
1634
1635 #ifdef DIAGNOSTIC
1636         if (!reqh->isreq)
1637                 panic("uhci_ctrl_done: not a request\n");
1638 #endif
1639
1640         LIST_REMOVE(ii, list);  /* remove from active list */
1641
1642         uhci_remove_ctrl(sc, upipe->u.ctl.sqh);
1643
1644         if (len != 0) {
1645                 dma = &upipe->u.ctl.datadma;
1646                 if (reqh->request.bmRequestType & UT_READ)
1647                         memcpy(reqh->buffer, KERNADDR(dma), len);
1648                 uhci_free_std_chain(sc, htd->link.std, ii->stdend);
1649                 usb_freemem(sc->sc_dmatag, dma);
1650         }
1651         DPRINTFN(5, ("uhci_ctrl_done: length=%d\n", reqh->actlen));
1652 }
1653
1654 /* Deallocate request data structures */
1655 void
1656 uhci_bulk_done(ii)
1657         uhci_intr_info_t *ii;
1658 {
1659         uhci_softc_t *sc = ii->sc;
1660         usbd_request_handle reqh = ii->reqh;
1661         struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe;
1662         u_int len = upipe->u.bulk.length;
1663         usb_dma_t *dma;
1664         uhci_td_t *htd = ii->stdstart->td;
1665
1666         LIST_REMOVE(ii, list);  /* remove from active list */
1667
1668         uhci_remove_bulk(sc, upipe->u.bulk.sqh);
1669
1670         if (len != 0) {
1671                 dma = &upipe->u.bulk.datadma;
1672                 if (upipe->u.bulk.isread && len != 0)
1673                         memcpy(reqh->buffer, KERNADDR(dma), len);
1674                 uhci_free_std_chain(sc, htd->link.std, 0);
1675                 usb_freemem(sc->sc_dmatag, dma);
1676         }
1677         DPRINTFN(4, ("uhci_bulk_done: length=%d\n", reqh->actlen));
1678         /* XXX compute new toggle */
1679 }
1680
1681 /* Add interrupt QH, called with vflock. */
1682 void
1683 uhci_add_intr(sc, n, sqh)
1684         uhci_softc_t *sc;
1685         int n;
1686         uhci_soft_qh_t *sqh;
1687 {
1688         struct uhci_vframe *vf = &sc->sc_vframes[n];
1689         uhci_qh_t *eqh;
1690
1691         DPRINTFN(4, ("uhci_add_intr: n=%d sqh=%p\n", n, sqh));
1692         eqh = vf->eqh->qh;
1693         sqh->qh->hlink     = eqh->hlink;
1694         sqh->qh->qh_hlink  = eqh->qh_hlink;
1695         eqh->hlink         = sqh;
1696         eqh->qh_hlink      = sqh->physaddr | UHCI_PTR_Q;
1697         vf->eqh = sqh;
1698         vf->bandwidth++;
1699 }
1700
1701 /* Remove interrupt QH, called with vflock. */
1702 void
1703 uhci_remove_intr(sc, n, sqh)
1704         uhci_softc_t *sc;
1705         int n;
1706         uhci_soft_qh_t *sqh;
1707 {
1708         struct uhci_vframe *vf = &sc->sc_vframes[n];
1709         uhci_soft_qh_t *pqh;
1710
1711         DPRINTFN(4, ("uhci_remove_intr: n=%d sqh=%p\n", n, sqh));
1712
1713         for (pqh = vf->hqh; pqh->qh->hlink != sqh; pqh = pqh->qh->hlink)
1714 #if defined(DIAGNOSTIC) || defined(USB_DEBUG)           
1715                 if (pqh->qh->qh_hlink & UHCI_PTR_T) {
1716                         printf("uhci_remove_intr: QH not found\n");
1717                         return;
1718                 }
1719 #else
1720                 ;
1721 #endif
1722         pqh->qh->hlink    = sqh->qh->hlink;
1723         pqh->qh->qh_hlink = sqh->qh->qh_hlink;
1724         if (vf->eqh == sqh)
1725                 vf->eqh = pqh;
1726         vf->bandwidth--;
1727 }
1728
1729 usbd_status
1730 uhci_device_setintr(sc, upipe, ival)
1731         uhci_softc_t *sc;
1732         struct uhci_pipe *upipe;
1733         int ival;
1734 {
1735         uhci_soft_qh_t *sqh;
1736         int i, npoll, s;
1737         u_int bestbw, bw, bestoffs, offs;
1738
1739         DPRINTFN(2, ("uhci_setintr: pipe=%p\n", upipe));
1740         if (ival == 0) {
1741                 printf("uhci_setintr: 0 interval\n");
1742                 return (USBD_INVAL);
1743         }
1744
1745         if (ival > UHCI_VFRAMELIST_COUNT)
1746                 ival = UHCI_VFRAMELIST_COUNT;
1747         npoll = (UHCI_VFRAMELIST_COUNT + ival - 1) / ival;
1748         DPRINTFN(2, ("uhci_setintr: ival=%d npoll=%d\n", ival, npoll));
1749
1750         upipe->u.intr.npoll = npoll;
1751         upipe->u.intr.qhs = 
1752                 malloc(npoll * sizeof(uhci_soft_qh_t *), M_USB, M_WAITOK);
1753
1754         /* 
1755          * Figure out which offset in the schedule that has most
1756          * bandwidth left over.
1757          */
1758 #define MOD(i) ((i) & (UHCI_VFRAMELIST_COUNT-1))
1759         for (bestoffs = offs = 0, bestbw = ~0; offs < ival; offs++) {
1760                 for (bw = i = 0; i < npoll; i++)
1761                         bw += sc->sc_vframes[MOD(i * ival + offs)].bandwidth;
1762                 if (bw < bestbw) {
1763                         bestbw = bw;
1764                         bestoffs = offs;
1765                 }
1766         }
1767         DPRINTFN(1, ("uhci_setintr: bw=%d offs=%d\n", bestbw, bestoffs));
1768
1769         upipe->iinfo->stdstart = 0;
1770         for(i = 0; i < npoll; i++) {
1771                 upipe->u.intr.qhs[i] = sqh = uhci_alloc_sqh(sc);
1772                 sqh->qh->elink = 0;
1773                 sqh->qh->qh_elink = UHCI_PTR_T;
1774                 sqh->pos = MOD(i * ival + bestoffs);
1775                 sqh->intr_info = upipe->iinfo;
1776         }
1777 #undef MOD
1778
1779         s = splusb();
1780         LIST_INSERT_HEAD(&sc->sc_intrhead, upipe->iinfo, list);
1781         splx(s);
1782
1783         uhci_lock_frames(sc);
1784         /* Enter QHs into the controller data structures. */
1785         for(i = 0; i < npoll; i++)
1786                 uhci_add_intr(sc, upipe->u.intr.qhs[i]->pos, 
1787                               upipe->u.intr.qhs[i]);
1788         uhci_unlock_frames(sc);
1789
1790         DPRINTFN(5, ("uhci_setintr: returns %p\n", upipe));
1791         return (USBD_NORMAL_COMPLETION);
1792 }
1793
1794 /* Open a new pipe. */
1795 usbd_status
1796 uhci_open(pipe)
1797         usbd_pipe_handle pipe;
1798 {
1799         uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus;
1800         struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
1801         usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc;
1802         usbd_status r;
1803
1804         DPRINTFN(1, ("uhci_open: pipe=%p, addr=%d, endpt=%d (%d)\n",
1805                      pipe, pipe->device->address, 
1806                      ed->bEndpointAddress, sc->sc_addr));
1807         if (pipe->device->address == sc->sc_addr) {
1808                 switch (ed->bEndpointAddress) {
1809                 case USB_CONTROL_ENDPOINT:
1810                         pipe->methods = &uhci_root_ctrl_methods;
1811                         break;
1812                 case UE_IN | UHCI_INTR_ENDPT:
1813                         pipe->methods = &uhci_root_intr_methods;
1814                         break;
1815                 default:
1816                         return (USBD_INVAL);
1817                 }
1818         } else {
1819                 upipe->iinfo = uhci_alloc_intr_info(sc);
1820                 if (upipe->iinfo == 0)
1821                         return (USBD_NOMEM);
1822                 switch (ed->bmAttributes & UE_XFERTYPE) {
1823                 case UE_CONTROL:
1824                         pipe->methods = &uhci_device_ctrl_methods;
1825                         upipe->u.ctl.sqh = uhci_alloc_sqh(sc);
1826                         if (upipe->u.ctl.sqh == 0)
1827                                 goto bad;
1828                         upipe->u.ctl.setup = uhci_alloc_std(sc);
1829                         if (upipe->u.ctl.setup == 0) {
1830                                 uhci_free_sqh(sc, upipe->u.ctl.sqh);
1831                                 goto bad;
1832                         }
1833                         upipe->u.ctl.stat = uhci_alloc_std(sc);
1834                         if (upipe->u.ctl.stat == 0) {
1835                                 uhci_free_sqh(sc, upipe->u.ctl.sqh);
1836                                 uhci_free_std(sc, upipe->u.ctl.setup);
1837                                 goto bad;
1838                         }
1839                         r = usb_allocmem(sc->sc_dmatag, 
1840                                          sizeof(usb_device_request_t), 
1841                                          0, &upipe->u.ctl.reqdma);
1842                         if (r != USBD_NORMAL_COMPLETION) {
1843                                 uhci_free_sqh(sc, upipe->u.ctl.sqh);
1844                                 uhci_free_std(sc, upipe->u.ctl.setup);
1845                                 uhci_free_std(sc, upipe->u.ctl.stat);
1846                                 goto bad;
1847                         }
1848                         break;
1849                 case UE_INTERRUPT:
1850                         pipe->methods = &uhci_device_intr_methods;
1851                         return (uhci_device_setintr(sc, upipe, ed->bInterval));
1852                 case UE_ISOCHRONOUS:
1853                         printf("uhci_open: iso not implemented\n");
1854                         return (USBD_XXX);
1855                 case UE_BULK:
1856                         pipe->methods = &uhci_device_bulk_methods;
1857                         upipe->u.bulk.sqh = uhci_alloc_sqh(sc);
1858                         if (upipe->u.bulk.sqh == 0)
1859                                 goto bad;
1860                         break;
1861                 }
1862         }
1863         return (USBD_NORMAL_COMPLETION);
1864
1865  bad:
1866         uhci_free_intr_info(upipe->iinfo);
1867         return (USBD_NOMEM);
1868 }
1869
1870 /*
1871  * Data structures and routines to emulate the root hub.
1872  */
1873 usb_device_descriptor_t uhci_devd = {
1874         USB_DEVICE_DESCRIPTOR_SIZE,
1875         UDESC_DEVICE,           /* type */
1876         {0x00, 0x01},           /* USB version */
1877         UCLASS_HUB,             /* class */
1878         USUBCLASS_HUB,          /* subclass */
1879         0,                      /* protocol */
1880         64,                     /* max packet */
1881         {0},{0},{0x00,0x01},    /* device id */
1882         1,2,0,                  /* string indicies */
1883         1                       /* # of configurations */
1884 };
1885
1886 usb_config_descriptor_t uhci_confd = {
1887         USB_CONFIG_DESCRIPTOR_SIZE,
1888         UDESC_CONFIG,
1889         {USB_CONFIG_DESCRIPTOR_SIZE +
1890          USB_INTERFACE_DESCRIPTOR_SIZE +
1891          USB_ENDPOINT_DESCRIPTOR_SIZE},
1892         1,
1893         1,
1894         0,
1895         UC_SELF_POWERED,
1896         0                       /* max power */
1897 };
1898
1899 usb_interface_descriptor_t uhci_ifcd = {
1900         USB_INTERFACE_DESCRIPTOR_SIZE,
1901         UDESC_INTERFACE,
1902         0,
1903         0,
1904         1,
1905         UCLASS_HUB,
1906         USUBCLASS_HUB,
1907         0,
1908         0
1909 };
1910
1911 usb_endpoint_descriptor_t uhci_endpd = {
1912         USB_ENDPOINT_DESCRIPTOR_SIZE,
1913         UDESC_ENDPOINT,
1914         UE_IN | UHCI_INTR_ENDPT,
1915         UE_INTERRUPT,
1916         {8},
1917         255
1918 };
1919
1920 usb_hub_descriptor_t uhci_hubd_piix = {
1921         USB_HUB_DESCRIPTOR_SIZE,
1922         UDESC_HUB,
1923         2,
1924         { UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL, 0 },
1925         50,                     /* power on to power good */
1926         0,
1927         { 0x00 },               /* both ports are removable */
1928         { 0x00 },               /* no ports can power down individually */
1929 };
1930
1931 int
1932 uhci_str(p, l, s)
1933         usb_string_descriptor_t *p;
1934         int l;
1935         char *s;
1936 {
1937         int i;
1938
1939         if (l == 0)
1940                 return (0);
1941         p->bLength = 2 * strlen(s) + 2;
1942         if (l == 1)
1943                 return (1);
1944         p->bDescriptorType = UDESC_STRING;
1945         l -= 2;
1946         for (i = 0; s[i] && l > 1; i++, l -= 2)
1947                 USETW2(p->bString[i], 0, s[i]);
1948         return (2*i+2);
1949 }
1950
1951 /*
1952  * Simulate a hardware hub by handling all the necessary requests.
1953  */
1954 usbd_status
1955 uhci_root_ctrl_transfer(reqh)
1956         usbd_request_handle reqh;
1957 {
1958         uhci_softc_t *sc = (uhci_softc_t *)reqh->pipe->device->bus;
1959         usb_device_request_t *req;
1960         void *buf;
1961         int port, x;
1962         int len, value, index, status, change, l, totlen = 0;
1963         usb_port_status_t ps;
1964         usbd_status r;
1965
1966         if (!reqh->isreq)
1967                 panic("uhci_root_ctrl_transfer: not a request\n");
1968         req = &reqh->request;
1969         buf = reqh->buffer;
1970
1971         DPRINTFN(2,("uhci_root_ctrl_control type=0x%02x request=%02x\n", 
1972                     req->bmRequestType, req->bRequest));
1973
1974         len = UGETW(req->wLength);
1975         value = UGETW(req->wValue);
1976         index = UGETW(req->wIndex);
1977 #define C(x,y) ((x) | ((y) << 8))
1978         switch(C(req->bRequest, req->bmRequestType)) {
1979         case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE):
1980         case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE):
1981         case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT):
1982                 /* 
1983                  * DEVICE_REMOTE_WAKEUP and ENDPOINT_STALL are no-ops
1984                  * for the integrated root hub.
1985                  */
1986                 break;
1987         case C(UR_GET_CONFIG, UT_READ_DEVICE):
1988                 if (len > 0) {
1989                         *(u_int8_t *)buf = sc->sc_conf;
1990                         totlen = 1;
1991                 }
1992                 break;
1993         case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
1994                 DPRINTFN(2,("uhci_root_ctrl_control wValue=0x%04x\n", value));
1995                 switch(value >> 8) {
1996                 case UDESC_DEVICE:
1997                         if ((value & 0xff) != 0) {
1998                                 r = USBD_IOERROR;
1999                                 goto ret;
2000                         }
2001                         totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE);
2002                         memcpy(buf, &uhci_devd, l);
2003                         break;
2004                 case UDESC_CONFIG:
2005                         if ((value & 0xff) != 0) {
2006                                 r = USBD_IOERROR;
2007                                 goto ret;
2008                         }
2009                         totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE);
2010                         memcpy(buf, &uhci_confd, l);
2011                         buf = (char *)buf + l;
2012                         len -= l;
2013                         l = min(len, USB_INTERFACE_DESCRIPTOR_SIZE);
2014                         totlen += l;
2015                         memcpy(buf, &uhci_ifcd, l);
2016                         buf = (char *)buf + l;
2017                         len -= l;
2018                         l = min(len, USB_ENDPOINT_DESCRIPTOR_SIZE);
2019                         totlen += l;
2020                         memcpy(buf, &uhci_endpd, l);
2021                         break;
2022                 case UDESC_STRING:
2023                         if (len == 0)
2024                                 break;
2025                         *(u_int8_t *)buf = 0;
2026                         totlen = 1;
2027                         switch (value & 0xff) {
2028                         case 1: /* Vendor */
2029                                 totlen = uhci_str(buf, len, sc->sc_vendor);
2030                                 break;
2031                         case 2: /* Product */
2032                                 totlen = uhci_str(buf, len, "UHCI root hub");
2033                                 break;
2034                         }
2035                         break;
2036                 default:
2037                         r = USBD_IOERROR;
2038                         goto ret;
2039                 }
2040                 break;
2041         case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
2042                 if (len > 0) {
2043                         *(u_int8_t *)buf = 0;
2044                         totlen = 1;
2045                 }
2046                 break;
2047         case C(UR_GET_STATUS, UT_READ_DEVICE):
2048                 if (len > 1) {
2049                         USETW(((usb_status_t *)buf)->wStatus,UDS_SELF_POWERED);
2050                         totlen = 2;
2051                 }
2052                 break;
2053         case C(UR_GET_STATUS, UT_READ_INTERFACE):
2054         case C(UR_GET_STATUS, UT_READ_ENDPOINT):
2055                 if (len > 1) {
2056                         USETW(((usb_status_t *)buf)->wStatus, 0);
2057                         totlen = 2;
2058                 }
2059                 break;
2060         case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
2061                 if (value >= USB_MAX_DEVICES) {
2062                         r = USBD_IOERROR;
2063                         goto ret;
2064                 }
2065                 sc->sc_addr = value;
2066                 break;
2067         case C(UR_SET_CONFIG, UT_WRITE_DEVICE):
2068                 if (value != 0 && value != 1) {
2069                         r = USBD_IOERROR;
2070                         goto ret;
2071                 }
2072                 sc->sc_conf = value;
2073                 break;
2074         case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE):
2075                 break;
2076         case C(UR_SET_FEATURE, UT_WRITE_DEVICE):
2077         case C(UR_SET_FEATURE, UT_WRITE_INTERFACE):
2078         case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
2079                 r = USBD_IOERROR;
2080                 goto ret;
2081         case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
2082                 break;
2083         case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT):
2084                 break;
2085         /* Hub requests */
2086         case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE):
2087                 break;
2088         case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER):
2089                 DPRINTFN(3, ("uhci_root_ctrl_control: UR_CLEAR_PORT_FEATURE port=%d feature=%d\n",
2090                              index, value));
2091                 if (index == 1)
2092                         port = UHCI_PORTSC1;
2093                 else if (index == 2)
2094                         port = UHCI_PORTSC2;
2095                 else {
2096                         r = USBD_IOERROR;
2097                         goto ret;
2098                 }
2099                 switch(value) {
2100                 case UHF_PORT_ENABLE:
2101                         x = UREAD2(sc, port);
2102                         UWRITE2(sc, port, x & ~UHCI_PORTSC_PE);
2103                         break;
2104                 case UHF_PORT_SUSPEND:
2105                         x = UREAD2(sc, port);
2106                         UWRITE2(sc, port, x & ~UHCI_PORTSC_SUSP);
2107                         break;
2108                 case UHF_PORT_RESET:
2109                         x = UREAD2(sc, port);
2110                         UWRITE2(sc, port, x & ~UHCI_PORTSC_PR);
2111                         break;
2112                 case UHF_C_PORT_CONNECTION:
2113                         x = UREAD2(sc, port);
2114                         UWRITE2(sc, port, x | UHCI_PORTSC_CSC);
2115                         break;
2116                 case UHF_C_PORT_ENABLE:
2117                         x = UREAD2(sc, port);
2118                         UWRITE2(sc, port, x | UHCI_PORTSC_POEDC);
2119                         break;
2120                 case UHF_C_PORT_OVER_CURRENT:
2121                         x = UREAD2(sc, port);
2122                         UWRITE2(sc, port, x | UHCI_PORTSC_OCIC);
2123                         break;
2124                 case UHF_C_PORT_RESET:
2125                         sc->sc_isreset = 0;
2126                         r = USBD_NORMAL_COMPLETION;
2127                         goto ret;
2128                 case UHF_PORT_CONNECTION:
2129                 case UHF_PORT_OVER_CURRENT:
2130                 case UHF_PORT_POWER:
2131                 case UHF_PORT_LOW_SPEED:
2132                 case UHF_C_PORT_SUSPEND:
2133                 default:
2134                         r = USBD_IOERROR;
2135                         goto ret;
2136                 }
2137                 break;
2138         case C(UR_GET_BUS_STATE, UT_READ_CLASS_OTHER):
2139                 if (index == 1)
2140                         port = UHCI_PORTSC1;
2141                 else if (index == 2)
2142                         port = UHCI_PORTSC2;
2143                 else {
2144                         r = USBD_IOERROR;
2145                         goto ret;
2146                 }
2147                 if (len > 0) {
2148                         *(u_int8_t *)buf = 
2149                                 (UREAD2(sc, port) & UHCI_PORTSC_LS) >>
2150                                 UHCI_PORTSC_LS_SHIFT;
2151                         totlen = 1;
2152                 }
2153                 break;
2154         case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
2155                 if (value != 0) {
2156                         r = USBD_IOERROR;
2157                         goto ret;
2158                 }
2159                 l = min(len, USB_HUB_DESCRIPTOR_SIZE);
2160                 totlen = l;
2161                 memcpy(buf, &uhci_hubd_piix, l);
2162                 break;
2163         case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
2164                 if (len != 4) {
2165                         r = USBD_IOERROR;
2166                         goto ret;
2167                 }
2168                 memset(buf, 0, len);
2169                 totlen = len;
2170                 break;
2171         case C(UR_GET_STATUS, UT_READ_CLASS_OTHER):
2172                 if (index == 1)
2173                         port = UHCI_PORTSC1;
2174                 else if (index == 2)
2175                         port = UHCI_PORTSC2;
2176                 else {
2177                         r = USBD_IOERROR;
2178                         goto ret;
2179                 }
2180                 if (len != 4) {
2181                         r = USBD_IOERROR;
2182                         goto ret;
2183                 }
2184                 x = UREAD2(sc, port);
2185                 status = change = 0;
2186                 if (x & UHCI_PORTSC_CCS  )
2187                         status |= UPS_CURRENT_CONNECT_STATUS;
2188                 if (x & UHCI_PORTSC_CSC  ) 
2189                         change |= UPS_C_CONNECT_STATUS;
2190                 if (x & UHCI_PORTSC_PE   ) 
2191                         status |= UPS_PORT_ENABLED;
2192                 if (x & UHCI_PORTSC_POEDC) 
2193                         change |= UPS_C_PORT_ENABLED;
2194                 if (x & UHCI_PORTSC_OCI  ) 
2195                         status |= UPS_OVERCURRENT_INDICATOR;
2196                 if (x & UHCI_PORTSC_OCIC ) 
2197                         change |= UPS_C_OVERCURRENT_INDICATOR;
2198                 if (x & UHCI_PORTSC_SUSP ) 
2199                         status |= UPS_SUSPEND;
2200                 if (x & UHCI_PORTSC_LSDA ) 
2201                         status |= UPS_LOW_SPEED;
2202                 status |= UPS_PORT_POWER;
2203                 if (sc->sc_isreset)
2204                         change |= UPS_C_PORT_RESET;
2205                 USETW(ps.wPortStatus, status);
2206                 USETW(ps.wPortChange, change);
2207                 l = min(len, sizeof ps);
2208                 memcpy(buf, &ps, l);
2209                 totlen = l;
2210                 break;
2211         case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
2212                 r = USBD_IOERROR;
2213                 goto ret;
2214         case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE):
2215                 break;
2216         case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER):
2217                 if (index == 1)
2218                         port = UHCI_PORTSC1;
2219                 else if (index == 2)
2220                         port = UHCI_PORTSC2;
2221                 else {
2222                         r = USBD_IOERROR;
2223                         goto ret;
2224                 }
2225                 switch(value) {
2226                 case UHF_PORT_ENABLE:
2227                         x = UREAD2(sc, port);
2228                         UWRITE2(sc, port, x | UHCI_PORTSC_PE);
2229                         break;
2230                 case UHF_PORT_SUSPEND:
2231                         x = UREAD2(sc, port);
2232                         UWRITE2(sc, port, x | UHCI_PORTSC_SUSP);
2233                         break;
2234                 case UHF_PORT_RESET:
2235                         x = UREAD2(sc, port);
2236                         UWRITE2(sc, port, x | UHCI_PORTSC_PR);
2237                         usbd_delay_ms(&sc->sc_bus, 10);
2238                         UWRITE2(sc, port, x & ~UHCI_PORTSC_PR);
2239                         delay(100);
2240                         x = UREAD2(sc, port);
2241                         UWRITE2(sc, port, x  | UHCI_PORTSC_PE);
2242                         delay(100);
2243                         DPRINTFN(3,("uhci port %d reset, status = 0x%04x\n",
2244                                     index, UREAD2(sc, port)));
2245                         sc->sc_isreset = 1;
2246                         break;
2247                 case UHF_C_PORT_CONNECTION:
2248                 case UHF_C_PORT_ENABLE:
2249                 case UHF_C_PORT_OVER_CURRENT:
2250                 case UHF_PORT_CONNECTION:
2251                 case UHF_PORT_OVER_CURRENT:
2252                 case UHF_PORT_POWER:
2253                 case UHF_PORT_LOW_SPEED:
2254                 case UHF_C_PORT_SUSPEND:
2255                 case UHF_C_PORT_RESET:
2256                 default:
2257                         r = USBD_IOERROR;
2258                         goto ret;
2259                 }
2260                 break;
2261         default:
2262                 r = USBD_IOERROR;
2263                 goto ret;
2264         }
2265         reqh->actlen = totlen;
2266         r = USBD_NORMAL_COMPLETION;
2267  ret:
2268         reqh->status = r;
2269         reqh->xfercb(reqh);
2270         return (USBD_IN_PROGRESS);
2271 }
2272
2273 /* Abort a root control request. */
2274 void
2275 uhci_root_ctrl_abort(reqh)
2276         usbd_request_handle reqh;
2277 {
2278         /* Nothing to do, all transfers are syncronous. */
2279 }
2280
2281 /* Close the root pipe. */
2282 void
2283 uhci_root_ctrl_close(pipe)
2284         usbd_pipe_handle pipe;
2285 {
2286 #if defined(__NetBSD__)
2287         untimeout(uhci_timo, pipe->intrreqh);
2288 #elif defined(__FreeBSD__)
2289         untimeout(uhci_timo, pipe->intrreqh, pipe->intrreqh->callout_handler);
2290 #endif
2291         DPRINTF(("uhci_root_ctrl_close\n"));
2292 }
2293
2294 /* Abort a root interrupt request. */
2295 void
2296 uhci_root_intr_abort(reqh)
2297         usbd_request_handle reqh;
2298 {
2299 #if defined(__NetBSD__)
2300         untimeout(uhci_timo, reqh);
2301 #elif defined(__FreeBSD__)
2302         untimeout(uhci_timo, reqh, reqh->callout_handler);
2303 #endif
2304 }
2305
2306 /* Start a transfer on the root interrupt pipe */
2307 usbd_status
2308 uhci_root_intr_transfer(reqh)
2309         usbd_request_handle reqh;
2310 {
2311         usbd_pipe_handle pipe = reqh->pipe;
2312         uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus;
2313         struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
2314         usb_dma_t *dmap;
2315         usbd_status r;
2316         int len;
2317
2318         DPRINTFN(3, ("uhci_root_intr_transfer: reqh=%p buf=%p len=%d flags=%d\n",
2319                      reqh, reqh->buffer, reqh->length, reqh->flags));
2320
2321         len = reqh->length;
2322         dmap = &upipe->u.intr.datadma;
2323         if (len == 0)
2324                 return (USBD_INVAL); /* XXX should it be? */
2325
2326         r = usb_allocmem(sc->sc_dmatag, len, 0, dmap);
2327         if (r != USBD_NORMAL_COMPLETION)
2328                 return (r);
2329
2330         sc->sc_ival = MS_TO_TICKS(reqh->pipe->endpoint->edesc->bInterval);
2331 #if defined(__NetBSD__)
2332         timeout(uhci_timo, reqh, sc->sc_ival);
2333 #elif defined(__FreeBSD__)
2334         /* To avoid race conditions we first initialise the struct
2335          * before we use it. The timeout happen between the setting
2336          * of the timeout and the setting of callout_handle
2337          */
2338         callout_handle_init(&reqh->callout_handler);
2339         reqh->callout_handler = timeout(uhci_timo, reqh, sc->sc_ival);
2340 #endif
2341         return (USBD_IN_PROGRESS);
2342 }
2343
2344 /* Close the root interrupt pipe. */
2345 void
2346 uhci_root_intr_close(pipe)
2347         usbd_pipe_handle pipe;
2348 {
2349 #if defined(__NetBSD__)
2350         untimeout(uhci_timo, pipe->intrreqh);
2351 #elif defined(__FreeBSD__)
2352         untimeout(uhci_timo, pipe->intrreqh, pipe->intrreqh->callout_handler);
2353 #endif
2354         DPRINTF(("uhci_root_intr_close\n"));
2355 }