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