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