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