uhci.c revision 1.89 1 /* $NetBSD: uhci.c,v 1.89 2000/03/23 07:01:46 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(__FreeBSD__)
857 callout_handle_init(&ii->timeout_handle);
858 #endif
859
860 return ii;
861 }
862
863 void
864 uhci_free_intr_info(ii)
865 uhci_intr_info_t *ii;
866 {
867 LIST_INSERT_HEAD(&uhci_ii_free, ii, list); /* and put on free list */
868 }
869
870 /* Add control QH, called at splusb(). */
871 void
872 uhci_add_ctrl(sc, sqh)
873 uhci_softc_t *sc;
874 uhci_soft_qh_t *sqh;
875 {
876 uhci_soft_qh_t *eqh;
877
878 SPLUSBCHECK;
879
880 DPRINTFN(10, ("uhci_add_ctrl: sqh=%p\n", sqh));
881 eqh = sc->sc_ctl_end;
882 sqh->hlink = eqh->hlink;
883 sqh->qh.qh_hlink = eqh->qh.qh_hlink;
884 eqh->hlink = sqh;
885 eqh->qh.qh_hlink = htole32(sqh->physaddr | UHCI_PTR_Q);
886 sc->sc_ctl_end = sqh;
887 }
888
889 /* Remove control QH, called at splusb(). */
890 void
891 uhci_remove_ctrl(sc, sqh)
892 uhci_softc_t *sc;
893 uhci_soft_qh_t *sqh;
894 {
895 uhci_soft_qh_t *pqh;
896
897 SPLUSBCHECK;
898
899 DPRINTFN(10, ("uhci_remove_ctrl: sqh=%p\n", sqh));
900 for (pqh = sc->sc_ctl_start; pqh->hlink != sqh; pqh=pqh->hlink)
901 #if defined(DIAGNOSTIC) || defined(UHCI_DEBUG)
902 if (le32toh(pqh->qh.qh_hlink) & UHCI_PTR_T) {
903 printf("uhci_remove_ctrl: QH not found\n");
904 return;
905 }
906 #else
907 ;
908 #endif
909 pqh->hlink = sqh->hlink;
910 pqh->qh.qh_hlink = sqh->qh.qh_hlink;
911 if (sc->sc_ctl_end == sqh)
912 sc->sc_ctl_end = pqh;
913 }
914
915 /* Add bulk QH, called at splusb(). */
916 void
917 uhci_add_bulk(sc, sqh)
918 uhci_softc_t *sc;
919 uhci_soft_qh_t *sqh;
920 {
921 uhci_soft_qh_t *eqh;
922
923 SPLUSBCHECK;
924
925 DPRINTFN(10, ("uhci_add_bulk: sqh=%p\n", sqh));
926 eqh = sc->sc_bulk_end;
927 sqh->hlink = eqh->hlink;
928 sqh->qh.qh_hlink = eqh->qh.qh_hlink;
929 eqh->hlink = sqh;
930 eqh->qh.qh_hlink = htole32(sqh->physaddr | UHCI_PTR_Q);
931 sc->sc_bulk_end = sqh;
932 }
933
934 /* Remove bulk QH, called at splusb(). */
935 void
936 uhci_remove_bulk(sc, sqh)
937 uhci_softc_t *sc;
938 uhci_soft_qh_t *sqh;
939 {
940 uhci_soft_qh_t *pqh;
941
942 SPLUSBCHECK;
943
944 DPRINTFN(10, ("uhci_remove_bulk: sqh=%p\n", sqh));
945 for (pqh = sc->sc_bulk_start; pqh->hlink != sqh; pqh = pqh->hlink)
946 #if defined(DIAGNOSTIC) || defined(UHCI_DEBUG)
947 if (le32toh(pqh->qh.qh_hlink) & UHCI_PTR_T) {
948 printf("uhci_remove_bulk: QH not found\n");
949 return;
950 }
951 #else
952 ;
953 #endif
954 pqh->hlink = sqh->hlink;
955 pqh->qh.qh_hlink = sqh->qh.qh_hlink;
956 if (sc->sc_bulk_end == sqh)
957 sc->sc_bulk_end = pqh;
958 }
959
960 int
961 uhci_intr(arg)
962 void *arg;
963 {
964 uhci_softc_t *sc = arg;
965 int status;
966 int ack;
967
968 #ifdef UHCI_DEBUG
969 if (uhcidebug > 15) {
970 DPRINTF(("%s: uhci_intr\n", USBDEVNAME(sc->sc_bus.bdev)));
971 uhci_dumpregs(sc);
972 }
973 #endif
974
975 status = UREAD2(sc, UHCI_STS);
976 if (status == 0) /* The interrupt was not for us. */
977 return (0);
978
979 #if defined(DIAGNOSTIC) && defined(__NetBSD__)
980 if (sc->sc_suspend != PWR_RESUME)
981 printf("uhci_intr: suspended sts=0x%x\n", status);
982 #endif
983
984 ack = 0;
985 if (status & UHCI_STS_USBINT)
986 ack |= UHCI_STS_USBINT;
987 if (status & UHCI_STS_USBEI)
988 ack |= UHCI_STS_USBEI;
989 if (status & UHCI_STS_RD) {
990 ack |= UHCI_STS_RD;
991 printf("%s: resume detect\n", USBDEVNAME(sc->sc_bus.bdev));
992 }
993 if (status & UHCI_STS_HSE) {
994 ack |= UHCI_STS_HSE;
995 printf("%s: host system error\n", USBDEVNAME(sc->sc_bus.bdev));
996 }
997 if (status & UHCI_STS_HCPE) {
998 ack |= UHCI_STS_HCPE;
999 printf("%s: host controller process error\n",
1000 USBDEVNAME(sc->sc_bus.bdev));
1001 }
1002 if (status & UHCI_STS_HCH) {
1003 /* no acknowledge needed */
1004 printf("%s: host controller halted\n",
1005 USBDEVNAME(sc->sc_bus.bdev));
1006 sc->sc_dying = 1;
1007 }
1008
1009 if (ack) /* acknowledge the ints */
1010 UWRITE2(sc, UHCI_STS, ack);
1011 else /* nothing to acknowledge */
1012 return (0);
1013
1014 sc->sc_bus.no_intrs++;
1015 usb_schedsoftintr(&sc->sc_bus);
1016
1017 DPRINTFN(10, ("%s: uhci_intr: exit\n", USBDEVNAME(sc->sc_bus.bdev)));
1018
1019 return (1);
1020 }
1021
1022 void
1023 uhci_softintr(bus)
1024 struct usbd_bus *bus;
1025 {
1026 uhci_softc_t *sc = (uhci_softc_t *)bus;
1027 uhci_intr_info_t *ii;
1028
1029 DPRINTFN(10,("%s: uhci_softintr\n", USBDEVNAME(sc->sc_bus.bdev)));
1030
1031 sc->sc_bus.intr_context++;
1032
1033 /*
1034 * Interrupts on UHCI really suck. When the host controller
1035 * interrupts because a transfer is completed there is no
1036 * way of knowing which transfer it was. You can scan down
1037 * the TDs and QHs of the previous frame to limit the search,
1038 * but that assumes that the interrupt was not delayed by more
1039 * than 1 ms, which may not always be true (e.g. after debug
1040 * output on a slow console).
1041 * We scan all interrupt descriptors to see if any have
1042 * completed.
1043 */
1044 for (ii = LIST_FIRST(&sc->sc_intrhead); ii; ii = LIST_NEXT(ii, list))
1045 uhci_check_intr(sc, ii);
1046
1047 sc->sc_bus.intr_context--;
1048 }
1049
1050 /* Check for an interrupt. */
1051 void
1052 uhci_check_intr(sc, ii)
1053 uhci_softc_t *sc;
1054 uhci_intr_info_t *ii;
1055 {
1056 uhci_soft_td_t *std, *lstd;
1057 u_int32_t status;
1058
1059 DPRINTFN(15, ("uhci_check_intr: ii=%p\n", ii));
1060 #ifdef DIAGNOSTIC
1061 if (ii == NULL) {
1062 printf("uhci_check_intr: no ii? %p\n", ii);
1063 return;
1064 }
1065 #endif
1066 if (ii->stdstart == NULL)
1067 return;
1068 lstd = ii->stdend;
1069 #ifdef DIAGNOSTIC
1070 if (lstd == NULL) {
1071 printf("uhci_check_intr: std==0\n");
1072 return;
1073 }
1074 #endif
1075 /*
1076 * If the last TD is still active we need to check whether there
1077 * is a an error somewhere in the middle, or whether there was a
1078 * short packet (SPD and not ACTIVE).
1079 */
1080 if (le32toh(lstd->td.td_status) & UHCI_TD_ACTIVE) {
1081 DPRINTFN(15, ("uhci_check_intr: active ii=%p\n", ii));
1082 for (std = ii->stdstart; std != lstd; std = std->link.std) {
1083 status = le32toh(std->td.td_status);
1084 /* If there's an active TD the xfer isn't done. */
1085 if (status & UHCI_TD_ACTIVE)
1086 break;
1087 /* Any kind of error makes the xfer done. */
1088 if (status & UHCI_TD_STALLED)
1089 goto done;
1090 /* We want short packets, and it is short: it's done */
1091 if ((status & UHCI_TD_SPD) &&
1092 UHCI_TD_GET_ACTLEN(status) <
1093 UHCI_TD_GET_MAXLEN(le32toh(std->td.td_token)))
1094 goto done;
1095 }
1096 DPRINTFN(15, ("uhci_check_intr: ii=%p std=%p still active\n",
1097 ii, ii->stdstart));
1098 return;
1099 }
1100 done:
1101 DPRINTFN(15, ("uhci_check_intr: ii=%p done\n", ii));
1102 usb_untimeout(uhci_timeout, ii, ii->timeout_handle);
1103 uhci_idone(ii);
1104 }
1105
1106 /* Called at splusb() */
1107 void
1108 uhci_idone(ii)
1109 uhci_intr_info_t *ii;
1110 {
1111 usbd_xfer_handle xfer = ii->xfer;
1112 struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
1113 uhci_soft_td_t *std;
1114 u_int32_t status = 0, nstatus;
1115 int actlen;
1116
1117 #ifdef DIAGNOSTIC
1118 {
1119 int s = splhigh();
1120 if (ii->isdone) {
1121 splx(s);
1122 printf("uhci_idone: ii=%p is done!\n", ii);
1123 return;
1124 }
1125 ii->isdone = 1;
1126 splx(s);
1127 }
1128 #endif
1129
1130 if (xfer->status == USBD_CANCELLED ||
1131 xfer->status == USBD_TIMEOUT) {
1132 DPRINTF(("uhci_idone: aborted xfer=%p\n", xfer));
1133 return;
1134 }
1135
1136 if (xfer->nframes != 0) {
1137 /* Isoc transfer, do things differently. */
1138 uhci_soft_td_t **stds = upipe->u.iso.stds;
1139 int i, n, nframes;
1140
1141 DPRINTFN(5,("uhci_idone: ii=%p isoc ready\n", ii));
1142
1143 nframes = xfer->nframes;
1144 actlen = 0;
1145 n = xfer->hcprivint;
1146 for (i = 0; i < nframes; i++) {
1147 std = stds[n];
1148 #ifdef UHCI_DEBUG
1149 if (uhcidebug > 5) {
1150 DPRINTFN(-1,("uhci_idone: isoc TD %d\n", i));
1151 uhci_dump_td(std);
1152 }
1153 #endif
1154 if (++n >= UHCI_VFRAMELIST_COUNT)
1155 n = 0;
1156 status = le32toh(std->td.td_status);
1157 actlen += UHCI_TD_GET_ACTLEN(status);
1158 }
1159 upipe->u.iso.inuse -= nframes;
1160 xfer->actlen = actlen;
1161 xfer->status = USBD_NORMAL_COMPLETION;
1162 xfer->hcpriv = ii;
1163 usb_transfer_complete(xfer);
1164 return;
1165 }
1166
1167 #ifdef UHCI_DEBUG
1168 DPRINTFN(10, ("uhci_idone: ii=%p, xfer=%p, pipe=%p ready\n",
1169 ii, xfer, upipe));
1170 if (uhcidebug > 10)
1171 uhci_dump_tds(ii->stdstart);
1172 #endif
1173
1174 /* The transfer is done, compute actual length and status. */
1175 actlen = 0;
1176 for (std = ii->stdstart; std != NULL; std = std->link.std) {
1177 nstatus = le32toh(std->td.td_status);
1178 if (nstatus & UHCI_TD_ACTIVE)
1179 break;
1180
1181 status = nstatus;
1182 if (UHCI_TD_GET_PID(le32toh(std->td.td_token)) !=
1183 UHCI_TD_PID_SETUP)
1184 actlen += UHCI_TD_GET_ACTLEN(status);
1185 }
1186 /* If there are left over TDs we need to update the toggle. */
1187 if (std != NULL)
1188 upipe->nexttoggle = UHCI_TD_GET_DT(le32toh(std->td.td_token));
1189
1190 status &= UHCI_TD_ERROR;
1191 DPRINTFN(10, ("uhci_check_intr: actlen=%d, status=0x%x\n",
1192 actlen, status));
1193 xfer->actlen = actlen;
1194 if (status != 0) {
1195 DPRINTFN((status == UHCI_TD_STALLED)*10,
1196 ("uhci_idone: error, addr=%d, endpt=0x%02x, "
1197 "status 0x%b\n",
1198 xfer->pipe->device->address,
1199 xfer->pipe->endpoint->edesc->bEndpointAddress,
1200 (int)status,
1201 "\20\22BITSTUFF\23CRCTO\24NAK\25BABBLE\26DBUFFER\27"
1202 "STALLED\30ACTIVE"));
1203 if (status == UHCI_TD_STALLED)
1204 xfer->status = USBD_STALLED;
1205 else
1206 xfer->status = USBD_IOERROR; /* more info XXX */
1207 } else {
1208 xfer->status = USBD_NORMAL_COMPLETION;
1209 }
1210 xfer->hcpriv = ii;
1211 usb_transfer_complete(xfer);
1212 }
1213
1214 /*
1215 * Called when a request does not complete.
1216 */
1217 void
1218 uhci_timeout(addr)
1219 void *addr;
1220 {
1221 uhci_intr_info_t *ii = addr;
1222
1223 DPRINTF(("uhci_timeout: ii=%p\n", ii));
1224
1225 #ifdef UHCI_DEBUG
1226 if (uhcidebug > 10)
1227 uhci_dump_tds(ii->stdstart);
1228 #endif
1229
1230 ii->xfer->device->bus->intr_context++;
1231 uhci_abort_xfer(ii->xfer, USBD_TIMEOUT);
1232 ii->xfer->device->bus->intr_context--;
1233 }
1234
1235 /*
1236 * Wait here until controller claims to have an interrupt.
1237 * Then call uhci_intr and return. Use timeout to avoid waiting
1238 * too long.
1239 * Only used during boot when interrupts are not enabled yet.
1240 */
1241 void
1242 uhci_waitintr(sc, xfer)
1243 uhci_softc_t *sc;
1244 usbd_xfer_handle xfer;
1245 {
1246 int timo = xfer->timeout;
1247 uhci_intr_info_t *ii;
1248
1249 DPRINTFN(10,("uhci_waitintr: timeout = %dms\n", timo));
1250
1251 xfer->status = USBD_IN_PROGRESS;
1252 for (; timo >= 0; timo--) {
1253 usb_delay_ms(&sc->sc_bus, 1);
1254 DPRINTFN(20,("uhci_waitintr: 0x%04x\n", UREAD2(sc, UHCI_STS)));
1255 if (UREAD2(sc, UHCI_STS) & UHCI_STS_USBINT) {
1256 uhci_intr(sc);
1257 if (xfer->status != USBD_IN_PROGRESS)
1258 return;
1259 }
1260 }
1261
1262 /* Timeout */
1263 DPRINTF(("uhci_waitintr: timeout\n"));
1264 for (ii = LIST_FIRST(&sc->sc_intrhead);
1265 ii != NULL && ii->xfer != xfer;
1266 ii = LIST_NEXT(ii, list))
1267 ;
1268 #ifdef DIAGNOSTIC
1269 if (ii == NULL)
1270 panic("uhci_waitintr: lost intr_info\n");
1271 #endif
1272 uhci_idone(ii);
1273 }
1274
1275 void
1276 uhci_poll(bus)
1277 struct usbd_bus *bus;
1278 {
1279 uhci_softc_t *sc = (uhci_softc_t *)bus;
1280
1281 if (UREAD2(sc, UHCI_STS) & UHCI_STS_USBINT)
1282 uhci_intr(sc);
1283 }
1284
1285 #if 0
1286 void
1287 uhci_reset(p)
1288 void *p;
1289 {
1290 uhci_softc_t *sc = p;
1291 int n;
1292
1293 UHCICMD(sc, UHCI_CMD_HCRESET);
1294 /* The reset bit goes low when the controller is done. */
1295 for (n = 0; n < UHCI_RESET_TIMEOUT &&
1296 (UREAD2(sc, UHCI_CMD) & UHCI_CMD_HCRESET); n++)
1297 delay(100);
1298 if (n >= UHCI_RESET_TIMEOUT)
1299 printf("%s: controller did not reset\n",
1300 USBDEVNAME(sc->sc_bus.bdev));
1301 }
1302 #endif
1303
1304 usbd_status
1305 uhci_run(sc, run)
1306 uhci_softc_t *sc;
1307 int run;
1308 {
1309 int s, n, running;
1310 u_int16_t cmd;
1311
1312 run = run != 0;
1313 s = splusb();
1314 DPRINTF(("uhci_run: setting run=%d\n", run));
1315 cmd = UREAD2(sc, UHCI_CMD);
1316 if (run)
1317 cmd |= UHCI_CMD_RS;
1318 else
1319 cmd &= ~UHCI_CMD_RS;
1320 UHCICMD(sc, cmd);
1321 for(n = 0; n < 10; n++) {
1322 running = !(UREAD2(sc, UHCI_STS) & UHCI_STS_HCH);
1323 /* return when we've entered the state we want */
1324 if (run == running) {
1325 splx(s);
1326 DPRINTF(("uhci_run: done cmd=0x%x sts=0x%x\n",
1327 UREAD2(sc, UHCI_CMD), UREAD2(sc, UHCI_STS)));
1328 return (USBD_NORMAL_COMPLETION);
1329 }
1330 usb_delay_ms(&sc->sc_bus, 1);
1331 }
1332 splx(s);
1333 printf("%s: cannot %s\n", USBDEVNAME(sc->sc_bus.bdev),
1334 run ? "start" : "stop");
1335 return (USBD_IOERROR);
1336 }
1337
1338 /*
1339 * Memory management routines.
1340 * uhci_alloc_std allocates TDs
1341 * uhci_alloc_sqh allocates QHs
1342 * These two routines do their own free list management,
1343 * partly for speed, partly because allocating DMAable memory
1344 * has page size granularaity so much memory would be wasted if
1345 * only one TD/QH (32 bytes) was placed in each allocated chunk.
1346 */
1347
1348 uhci_soft_td_t *
1349 uhci_alloc_std(sc)
1350 uhci_softc_t *sc;
1351 {
1352 uhci_soft_td_t *std;
1353 usbd_status err;
1354 int i, offs;
1355 usb_dma_t dma;
1356
1357 if (sc->sc_freetds == NULL) {
1358 DPRINTFN(2,("uhci_alloc_std: allocating chunk\n"));
1359 err = usb_allocmem(&sc->sc_bus, UHCI_STD_SIZE * UHCI_STD_CHUNK,
1360 UHCI_TD_ALIGN, &dma);
1361 if (err)
1362 return (0);
1363 for(i = 0; i < UHCI_STD_CHUNK; i++) {
1364 offs = i * UHCI_STD_SIZE;
1365 std = (uhci_soft_td_t *)((char *)KERNADDR(&dma) +offs);
1366 std->physaddr = DMAADDR(&dma) + offs;
1367 std->link.std = sc->sc_freetds;
1368 sc->sc_freetds = std;
1369 }
1370 }
1371 std = sc->sc_freetds;
1372 sc->sc_freetds = std->link.std;
1373 memset(&std->td, 0, sizeof(uhci_td_t));
1374 return std;
1375 }
1376
1377 void
1378 uhci_free_std(sc, std)
1379 uhci_softc_t *sc;
1380 uhci_soft_td_t *std;
1381 {
1382 #ifdef DIAGNOSTIC
1383 #define TD_IS_FREE 0x12345678
1384 if (le32toh(std->td.td_token) == TD_IS_FREE) {
1385 printf("uhci_free_std: freeing free TD %p\n", std);
1386 return;
1387 }
1388 std->td.td_token = htole32(TD_IS_FREE);
1389 #endif
1390 std->link.std = sc->sc_freetds;
1391 sc->sc_freetds = std;
1392 }
1393
1394 uhci_soft_qh_t *
1395 uhci_alloc_sqh(sc)
1396 uhci_softc_t *sc;
1397 {
1398 uhci_soft_qh_t *sqh;
1399 usbd_status err;
1400 int i, offs;
1401 usb_dma_t dma;
1402
1403 if (sc->sc_freeqhs == NULL) {
1404 DPRINTFN(2, ("uhci_alloc_sqh: allocating chunk\n"));
1405 err = usb_allocmem(&sc->sc_bus, UHCI_SQH_SIZE * UHCI_SQH_CHUNK,
1406 UHCI_QH_ALIGN, &dma);
1407 if (err)
1408 return (0);
1409 for(i = 0; i < UHCI_SQH_CHUNK; i++) {
1410 offs = i * UHCI_SQH_SIZE;
1411 sqh = (uhci_soft_qh_t *)((char *)KERNADDR(&dma) +offs);
1412 sqh->physaddr = DMAADDR(&dma) + offs;
1413 sqh->hlink = sc->sc_freeqhs;
1414 sc->sc_freeqhs = sqh;
1415 }
1416 }
1417 sqh = sc->sc_freeqhs;
1418 sc->sc_freeqhs = sqh->hlink;
1419 memset(&sqh->qh, 0, sizeof(uhci_qh_t));
1420 return (sqh);
1421 }
1422
1423 void
1424 uhci_free_sqh(sc, sqh)
1425 uhci_softc_t *sc;
1426 uhci_soft_qh_t *sqh;
1427 {
1428 sqh->hlink = sc->sc_freeqhs;
1429 sc->sc_freeqhs = sqh;
1430 }
1431
1432 #if 0
1433 /*
1434 * Enter a list of transfers onto a control queue.
1435 * Called at splusb()
1436 */
1437 void
1438 uhci_enter_ctl_q(sc, sqh, ii)
1439 uhci_softc_t *sc;
1440 uhci_soft_qh_t *sqh;
1441 uhci_intr_info_t *ii;
1442 {
1443 DPRINTFN(5, ("uhci_enter_ctl_q: sqh=%p\n", sqh));
1444
1445 }
1446 #endif
1447
1448 void
1449 uhci_free_std_chain(sc, std, stdend)
1450 uhci_softc_t *sc;
1451 uhci_soft_td_t *std;
1452 uhci_soft_td_t *stdend;
1453 {
1454 uhci_soft_td_t *p;
1455
1456 for (; std != stdend; std = p) {
1457 p = std->link.std;
1458 uhci_free_std(sc, std);
1459 }
1460 }
1461
1462 usbd_status
1463 uhci_alloc_std_chain(upipe, sc, len, rd, flags, dma, sp, ep)
1464 struct uhci_pipe *upipe;
1465 uhci_softc_t *sc;
1466 int len, rd;
1467 u_int16_t flags;
1468 usb_dma_t *dma;
1469 uhci_soft_td_t **sp, **ep;
1470 {
1471 uhci_soft_td_t *p, *lastp;
1472 uhci_physaddr_t lastlink;
1473 int i, ntd, l, tog, maxp;
1474 u_int32_t status;
1475 int addr = upipe->pipe.device->address;
1476 int endpt = upipe->pipe.endpoint->edesc->bEndpointAddress;
1477
1478 DPRINTFN(8, ("uhci_alloc_std_chain: addr=%d endpt=%d len=%d ls=%d "
1479 "flags=0x%x\n", addr, UE_GET_ADDR(endpt), len,
1480 upipe->pipe.device->lowspeed, flags));
1481 maxp = UGETW(upipe->pipe.endpoint->edesc->wMaxPacketSize);
1482 if (maxp == 0) {
1483 printf("uhci_alloc_std_chain: maxp=0\n");
1484 return (USBD_INVAL);
1485 }
1486 ntd = (len + maxp - 1) / maxp;
1487 if ((flags & USBD_FORCE_SHORT_XFER) && len % maxp == 0)
1488 ntd++;
1489 DPRINTFN(10, ("uhci_alloc_std_chain: maxp=%d ntd=%d\n", maxp, ntd));
1490 if (ntd == 0) {
1491 *sp = *ep = 0;
1492 DPRINTFN(-1,("uhci_alloc_std_chain: ntd=0\n"));
1493 return (USBD_NORMAL_COMPLETION);
1494 }
1495 tog = upipe->nexttoggle;
1496 if (ntd % 2 == 0)
1497 tog ^= 1;
1498 upipe->nexttoggle = tog ^ 1;
1499 lastp = 0;
1500 lastlink = UHCI_PTR_T;
1501 ntd--;
1502 status = UHCI_TD_ZERO_ACTLEN(UHCI_TD_SET_ERRCNT(3) | UHCI_TD_ACTIVE);
1503 if (upipe->pipe.device->lowspeed)
1504 status |= UHCI_TD_LS;
1505 if (flags & USBD_SHORT_XFER_OK)
1506 status |= UHCI_TD_SPD;
1507 for (i = ntd; i >= 0; i--) {
1508 p = uhci_alloc_std(sc);
1509 if (p == NULL) {
1510 uhci_free_std_chain(sc, lastp, 0);
1511 return (USBD_NOMEM);
1512 }
1513 p->link.std = lastp;
1514 if (lastlink == UHCI_PTR_T)
1515 p->td.td_link = htole32(lastlink);
1516 else
1517 p->td.td_link = htole32(lastlink|UHCI_PTR_VF);
1518 lastp = p;
1519 lastlink = p->physaddr;
1520 p->td.td_status = htole32(status);
1521 if (i == ntd) {
1522 /* last TD */
1523 l = len % maxp;
1524 if (l == 0 && !(flags & USBD_FORCE_SHORT_XFER))
1525 l = maxp;
1526 *ep = p;
1527 } else
1528 l = maxp;
1529 p->td.td_token =
1530 htole32(rd ? UHCI_TD_IN (l, endpt, addr, tog) :
1531 UHCI_TD_OUT(l, endpt, addr, tog));
1532 p->td.td_buffer = htole32(DMAADDR(dma) + i * maxp);
1533 tog ^= 1;
1534 }
1535 *sp = lastp;
1536 DPRINTFN(10, ("uhci_alloc_std_chain: nexttog=%d\n",
1537 upipe->nexttoggle));
1538 return (USBD_NORMAL_COMPLETION);
1539 }
1540
1541 void
1542 uhci_device_clear_toggle(pipe)
1543 usbd_pipe_handle pipe;
1544 {
1545 struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
1546 upipe->nexttoggle = 0;
1547 }
1548
1549 void
1550 uhci_noop(pipe)
1551 usbd_pipe_handle pipe;
1552 {
1553 }
1554
1555 usbd_status
1556 uhci_device_bulk_transfer(xfer)
1557 usbd_xfer_handle xfer;
1558 {
1559 usbd_status err;
1560
1561 /* Insert last in queue. */
1562 err = usb_insert_transfer(xfer);
1563 if (err)
1564 return (err);
1565
1566 /* Pipe isn't running (otherwise err would be USBD_INPROG),
1567 * start first
1568 */
1569 return (uhci_device_bulk_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
1570 }
1571
1572 usbd_status
1573 uhci_device_bulk_start(xfer)
1574 usbd_xfer_handle xfer;
1575 {
1576 struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
1577 usbd_device_handle dev = upipe->pipe.device;
1578 uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
1579 uhci_intr_info_t *ii = upipe->iinfo;
1580 uhci_soft_td_t *data, *dataend;
1581 uhci_soft_qh_t *sqh;
1582 usbd_status err;
1583 int len, isread, endpt;
1584 int s;
1585
1586 DPRINTFN(3, ("uhci_device_bulk_transfer: xfer=%p len=%d flags=%d\n",
1587 xfer, xfer->length, xfer->flags));
1588
1589 if (sc->sc_dying)
1590 return (USBD_IOERROR);
1591
1592 #ifdef DIAGNOSTIC
1593 if (xfer->rqflags & URQ_REQUEST)
1594 panic("uhci_device_bulk_transfer: a request\n");
1595 #endif
1596
1597 len = xfer->length;
1598 endpt = xfer->pipe->endpoint->edesc->bEndpointAddress;
1599 isread = UE_GET_DIR(endpt) == UE_DIR_IN;
1600 sqh = upipe->u.bulk.sqh;
1601
1602 upipe->u.bulk.isread = isread;
1603 upipe->u.bulk.length = len;
1604
1605 err = uhci_alloc_std_chain(upipe, sc, len, isread, xfer->flags,
1606 &xfer->dmabuf, &data, &dataend);
1607 if (err)
1608 return (err);
1609 dataend->td.td_status |= htole32(UHCI_TD_IOC);
1610
1611 #ifdef UHCI_DEBUG
1612 if (uhcidebug > 8) {
1613 DPRINTF(("uhci_device_bulk_transfer: data(1)\n"));
1614 uhci_dump_tds(data);
1615 }
1616 #endif
1617
1618 /* Set up interrupt info. */
1619 ii->xfer = xfer;
1620 ii->stdstart = data;
1621 ii->stdend = dataend;
1622 #if defined(__FreeBSD__)
1623 callout_handle_init(&ii->timeout_handle);
1624 #endif
1625 #ifdef DIAGNOSTIC
1626 if (!ii->isdone) {
1627 printf("uhci_device_bulk_transfer: not done, ii=%p\n", ii);
1628 }
1629 ii->isdone = 0;
1630 #endif
1631
1632 sqh->elink = data;
1633 sqh->qh.qh_elink = htole32(data->physaddr);
1634 sqh->intr_info = ii;
1635
1636 s = splusb();
1637 uhci_add_bulk(sc, sqh);
1638 LIST_INSERT_HEAD(&sc->sc_intrhead, ii, list);
1639
1640 if (xfer->timeout && !sc->sc_bus.use_polling) {
1641 usb_timeout(uhci_timeout, ii, MS_TO_TICKS(xfer->timeout),
1642 ii->timeout_handle);
1643 }
1644 splx(s);
1645
1646 #ifdef UHCI_DEBUG
1647 if (uhcidebug > 10) {
1648 DPRINTF(("uhci_device_bulk_transfer: data(2)\n"));
1649 uhci_dump_tds(data);
1650 }
1651 #endif
1652
1653 if (sc->sc_bus.use_polling)
1654 uhci_waitintr(sc, xfer);
1655
1656 return (USBD_IN_PROGRESS);
1657 }
1658
1659 /* Abort a device bulk request. */
1660 void
1661 uhci_device_bulk_abort(xfer)
1662 usbd_xfer_handle xfer;
1663 {
1664 DPRINTF(("uhci_device_bulk_abort:\n"));
1665 uhci_abort_xfer(xfer, USBD_CANCELLED);
1666 }
1667
1668 void
1669 uhci_abort_xfer(xfer, status)
1670 usbd_xfer_handle xfer;
1671 usbd_status status;
1672 {
1673 struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
1674 uhci_intr_info_t *ii = upipe->iinfo;
1675 uhci_soft_td_t *std;
1676
1677 DPRINTFN(1,("uhci_abort_xfer: xfer=%p, status=%d\n", xfer, status));
1678
1679 /* Make interrupt routine ignore it, */
1680 xfer->status = status;
1681
1682 /* don't timeout, */
1683 usb_untimeout(uhci_timeout, ii, ii->timeout_handle);
1684
1685 /* make hardware ignore it, */
1686 for (std = ii->stdstart; std != 0; std = std->link.std)
1687 std->td.td_status &= htole32(~(UHCI_TD_ACTIVE | UHCI_TD_IOC));
1688
1689 xfer->hcpriv = ii;
1690
1691 #if 1
1692 /* Make sure hardware has completed. */
1693 if (xfer->device->bus->intr_context) {
1694 /* We have no process context, so we can't use tsleep(). */
1695 callout_reset(&xfer->abort_handle, hz / USB_FRAMES_PER_SECOND,
1696 uhci_abort_xfer_end, xfer);
1697 } else {
1698 #if defined(DIAGNOSTIC) && defined(__i386__) && defined(__FreeBSD__)
1699 KASSERT(intr_nesting_level == 0,
1700 ("ohci_abort_req in interrupt context"));
1701 #endif
1702 usb_delay_ms(xfer->pipe->device->bus, 1);
1703 /* and call final part of interrupt handler. */
1704 uhci_abort_xfer_end(xfer);
1705 }
1706 #else
1707 delay(1000);
1708 uhci_abort_xfer_end(xfer);
1709 #endif
1710 }
1711
1712 void
1713 uhci_abort_xfer_end(v)
1714 void *v;
1715 {
1716 usbd_xfer_handle xfer = v;
1717 int s;
1718
1719 s = splusb();
1720 usb_transfer_complete(xfer);
1721 splx(s);
1722 }
1723
1724 /* Close a device bulk pipe. */
1725 void
1726 uhci_device_bulk_close(pipe)
1727 usbd_pipe_handle pipe;
1728 {
1729 struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
1730 usbd_device_handle dev = upipe->pipe.device;
1731 uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
1732
1733 uhci_free_sqh(sc, upipe->u.bulk.sqh);
1734 uhci_free_intr_info(upipe->iinfo);
1735 /* XXX free other resources */
1736 }
1737
1738 usbd_status
1739 uhci_device_ctrl_transfer(xfer)
1740 usbd_xfer_handle xfer;
1741 {
1742 usbd_status err;
1743
1744 /* Insert last in queue. */
1745 err = usb_insert_transfer(xfer);
1746 if (err)
1747 return (err);
1748
1749 /* Pipe isn't running (otherwise err would be USBD_INPROG),
1750 * start first
1751 */
1752 return (uhci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
1753 }
1754
1755 usbd_status
1756 uhci_device_ctrl_start(xfer)
1757 usbd_xfer_handle xfer;
1758 {
1759 uhci_softc_t *sc = (uhci_softc_t *)xfer->pipe->device->bus;
1760 usbd_status err;
1761
1762 if (sc->sc_dying)
1763 return (USBD_IOERROR);
1764
1765 #ifdef DIAGNOSTIC
1766 if (!(xfer->rqflags & URQ_REQUEST))
1767 panic("uhci_device_ctrl_transfer: not a request\n");
1768 #endif
1769
1770 err = uhci_device_request(xfer);
1771 if (err)
1772 return (err);
1773
1774 if (sc->sc_bus.use_polling)
1775 uhci_waitintr(sc, xfer);
1776 return (USBD_IN_PROGRESS);
1777 }
1778
1779 usbd_status
1780 uhci_device_intr_transfer(xfer)
1781 usbd_xfer_handle xfer;
1782 {
1783 usbd_status err;
1784
1785 /* Insert last in queue. */
1786 err = usb_insert_transfer(xfer);
1787 if (err)
1788 return (err);
1789
1790 /* Pipe isn't running (otherwise err would be USBD_INPROG),
1791 * start first
1792 */
1793 return (uhci_device_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
1794 }
1795
1796 usbd_status
1797 uhci_device_intr_start(xfer)
1798 usbd_xfer_handle xfer;
1799 {
1800 struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
1801 usbd_device_handle dev = upipe->pipe.device;
1802 uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
1803 uhci_intr_info_t *ii = upipe->iinfo;
1804 uhci_soft_td_t *data, *dataend;
1805 uhci_soft_qh_t *sqh;
1806 usbd_status err;
1807 int i, s;
1808
1809 if (sc->sc_dying)
1810 return (USBD_IOERROR);
1811
1812 DPRINTFN(3,("uhci_device_intr_transfer: xfer=%p len=%d flags=%d\n",
1813 xfer, xfer->length, xfer->flags));
1814
1815 #ifdef DIAGNOSTIC
1816 if (xfer->rqflags & URQ_REQUEST)
1817 panic("uhci_device_intr_transfer: a request\n");
1818 #endif
1819
1820 err = uhci_alloc_std_chain(upipe, sc, xfer->length, 1, xfer->flags,
1821 &xfer->dmabuf, &data, &dataend);
1822 if (err)
1823 return (err);
1824 dataend->td.td_status |= htole32(UHCI_TD_IOC);
1825
1826 #ifdef UHCI_DEBUG
1827 if (uhcidebug > 10) {
1828 DPRINTF(("uhci_device_intr_transfer: data(1)\n"));
1829 uhci_dump_tds(data);
1830 uhci_dump_qh(upipe->u.intr.qhs[0]);
1831 }
1832 #endif
1833
1834 s = splusb();
1835 /* Set up interrupt info. */
1836 ii->xfer = xfer;
1837 ii->stdstart = data;
1838 ii->stdend = dataend;
1839 #if defined(__FreeBSD__)
1840 callout_handle_init(&ii->timeout_handle);
1841 #endif
1842 #ifdef DIAGNOSTIC
1843 if (!ii->isdone) {
1844 printf("uhci_device_intr_transfer: not done, ii=%p\n", ii);
1845 }
1846 ii->isdone = 0;
1847 #endif
1848
1849 DPRINTFN(10,("uhci_device_intr_transfer: qhs[0]=%p\n",
1850 upipe->u.intr.qhs[0]));
1851 for (i = 0; i < upipe->u.intr.npoll; i++) {
1852 sqh = upipe->u.intr.qhs[i];
1853 sqh->elink = data;
1854 sqh->qh.qh_elink = htole32(data->physaddr);
1855 }
1856 splx(s);
1857
1858 #ifdef UHCI_DEBUG
1859 if (uhcidebug > 10) {
1860 DPRINTF(("uhci_device_intr_transfer: data(2)\n"));
1861 uhci_dump_tds(data);
1862 uhci_dump_qh(upipe->u.intr.qhs[0]);
1863 }
1864 #endif
1865
1866 return (USBD_IN_PROGRESS);
1867 }
1868
1869 /* Abort a device control request. */
1870 void
1871 uhci_device_ctrl_abort(xfer)
1872 usbd_xfer_handle xfer;
1873 {
1874 DPRINTF(("uhci_device_ctrl_abort:\n"));
1875 uhci_abort_xfer(xfer, USBD_CANCELLED);
1876 }
1877
1878 /* Close a device control pipe. */
1879 void
1880 uhci_device_ctrl_close(pipe)
1881 usbd_pipe_handle pipe;
1882 {
1883 struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
1884
1885 uhci_free_intr_info(upipe->iinfo);
1886 /* XXX free other resources? */
1887 }
1888
1889 /* Abort a device interrupt request. */
1890 void
1891 uhci_device_intr_abort(xfer)
1892 usbd_xfer_handle xfer;
1893 {
1894 DPRINTFN(1,("uhci_device_intr_abort: xfer=%p\n", xfer));
1895 if (xfer->pipe->intrxfer == xfer) {
1896 DPRINTFN(1,("uhci_device_intr_abort: remove\n"));
1897 xfer->pipe->intrxfer = 0;
1898 }
1899 uhci_abort_xfer(xfer, USBD_CANCELLED);
1900 }
1901
1902 /* Close a device interrupt pipe. */
1903 void
1904 uhci_device_intr_close(pipe)
1905 usbd_pipe_handle pipe;
1906 {
1907 struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
1908 uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus;
1909 int i, s, npoll;
1910
1911 upipe->iinfo->stdstart = 0; /* inactive */
1912
1913 /* Unlink descriptors from controller data structures. */
1914 npoll = upipe->u.intr.npoll;
1915 uhci_lock_frames(sc);
1916 for (i = 0; i < npoll; i++)
1917 uhci_remove_intr(sc, upipe->u.intr.qhs[i]->pos,
1918 upipe->u.intr.qhs[i]);
1919 uhci_unlock_frames(sc);
1920
1921 /*
1922 * We now have to wait for any activity on the physical
1923 * descriptors to stop.
1924 */
1925 usb_delay_ms(&sc->sc_bus, 2);
1926
1927 for(i = 0; i < npoll; i++)
1928 uhci_free_sqh(sc, upipe->u.intr.qhs[i]);
1929 free(upipe->u.intr.qhs, M_USBHC);
1930
1931 s = splusb();
1932 LIST_REMOVE(upipe->iinfo, list); /* remove from active list */
1933 splx(s);
1934 uhci_free_intr_info(upipe->iinfo);
1935
1936 /* XXX free other resources */
1937 }
1938
1939 usbd_status
1940 uhci_device_request(xfer)
1941 usbd_xfer_handle xfer;
1942 {
1943 struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
1944 usb_device_request_t *req = &xfer->request;
1945 usbd_device_handle dev = upipe->pipe.device;
1946 uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
1947 int addr = dev->address;
1948 int endpt = upipe->pipe.endpoint->edesc->bEndpointAddress;
1949 uhci_intr_info_t *ii = upipe->iinfo;
1950 uhci_soft_td_t *setup, *data, *stat, *next, *dataend;
1951 uhci_soft_qh_t *sqh;
1952 int len;
1953 u_int32_t ls;
1954 usbd_status err;
1955 int isread;
1956 int s;
1957
1958 DPRINTFN(3,("uhci_device_control type=0x%02x, request=0x%02x, "
1959 "wValue=0x%04x, wIndex=0x%04x len=%d, addr=%d, endpt=%d\n",
1960 req->bmRequestType, req->bRequest, UGETW(req->wValue),
1961 UGETW(req->wIndex), UGETW(req->wLength),
1962 addr, endpt));
1963
1964 ls = dev->lowspeed ? UHCI_TD_LS : 0;
1965 isread = req->bmRequestType & UT_READ;
1966 len = UGETW(req->wLength);
1967
1968 setup = upipe->u.ctl.setup;
1969 stat = upipe->u.ctl.stat;
1970 sqh = upipe->u.ctl.sqh;
1971
1972 /* Set up data transaction */
1973 if (len != 0) {
1974 upipe->nexttoggle = 1;
1975 err = uhci_alloc_std_chain(upipe, sc, len, isread, xfer->flags,
1976 &xfer->dmabuf, &data, &dataend);
1977 if (err)
1978 return (err);
1979 next = data;
1980 dataend->link.std = stat;
1981 dataend->td.td_link = htole32(stat->physaddr | UHCI_PTR_VF);
1982 } else {
1983 next = stat;
1984 }
1985 upipe->u.ctl.length = len;
1986
1987 memcpy(KERNADDR(&upipe->u.ctl.reqdma), req, sizeof *req);
1988
1989 setup->link.std = next;
1990 setup->td.td_link = htole32(next->physaddr | UHCI_PTR_VF);
1991 setup->td.td_status = htole32(UHCI_TD_SET_ERRCNT(3) | ls |
1992 UHCI_TD_ACTIVE);
1993 setup->td.td_token = htole32(UHCI_TD_SETUP(sizeof *req, endpt, addr));
1994 setup->td.td_buffer = htole32(DMAADDR(&upipe->u.ctl.reqdma));
1995
1996 stat->link.std = 0;
1997 stat->td.td_link = htole32(UHCI_PTR_T);
1998 stat->td.td_status = htole32(UHCI_TD_SET_ERRCNT(3) | ls |
1999 UHCI_TD_ACTIVE | UHCI_TD_IOC);
2000 stat->td.td_token =
2001 htole32(isread ? UHCI_TD_OUT(0, endpt, addr, 1) :
2002 UHCI_TD_IN (0, endpt, addr, 1));
2003 stat->td.td_buffer = htole32(0);
2004
2005 #ifdef UHCI_DEBUG
2006 if (uhcidebug > 10) {
2007 DPRINTF(("uhci_device_request: before transfer\n"));
2008 uhci_dump_tds(setup);
2009 }
2010 #endif
2011
2012 /* Set up interrupt info. */
2013 ii->xfer = xfer;
2014 ii->stdstart = setup;
2015 ii->stdend = stat;
2016 #if defined(__FreeBSD__)
2017 callout_handle_init(&ii->timeout_handle);
2018 #endif
2019 #ifdef DIAGNOSTIC
2020 if (!ii->isdone) {
2021 printf("uhci_device_request: not done, ii=%p\n", ii);
2022 }
2023 ii->isdone = 0;
2024 #endif
2025
2026 sqh->elink = setup;
2027 sqh->qh.qh_elink = htole32(setup->physaddr);
2028 sqh->intr_info = ii;
2029
2030 s = splusb();
2031 uhci_add_ctrl(sc, sqh);
2032 LIST_INSERT_HEAD(&sc->sc_intrhead, ii, list);
2033 #ifdef UHCI_DEBUG
2034 if (uhcidebug > 12) {
2035 uhci_soft_td_t *std;
2036 uhci_soft_qh_t *xqh;
2037 uhci_soft_qh_t *sxqh;
2038 int maxqh = 0;
2039 uhci_physaddr_t link;
2040 DPRINTF(("uhci_enter_ctl_q: follow from [0]\n"));
2041 for (std = sc->sc_vframes[0].htd, link = 0;
2042 (link & UHCI_PTR_Q) == 0;
2043 std = std->link.std) {
2044 link = le32toh(std->td.td_link);
2045 uhci_dump_td(std);
2046 }
2047 sxqh = (uhci_soft_qh_t *)std;
2048 uhci_dump_qh(sxqh);
2049 for (xqh = sxqh;
2050 xqh != NULL;
2051 xqh = (maxqh++ == 5 || xqh->hlink==sxqh ||
2052 xqh->hlink==xqh ? NULL : xqh->hlink)) {
2053 uhci_dump_qh(xqh);
2054 }
2055 DPRINTF(("Enqueued QH:\n"));
2056 uhci_dump_qh(sqh);
2057 uhci_dump_tds(sqh->elink);
2058 }
2059 #endif
2060 if (xfer->timeout && !sc->sc_bus.use_polling) {
2061 usb_timeout(uhci_timeout, ii,
2062 MS_TO_TICKS(xfer->timeout), ii->timeout_handle);
2063 }
2064 splx(s);
2065
2066 return (USBD_NORMAL_COMPLETION);
2067 }
2068
2069 usbd_status
2070 uhci_device_isoc_transfer(xfer)
2071 usbd_xfer_handle xfer;
2072 {
2073 usbd_status err;
2074
2075 DPRINTFN(5,("uhci_device_isoc_transfer: xfer=%p\n", xfer));
2076
2077 /* Put it on our queue, */
2078 err = usb_insert_transfer(xfer);
2079
2080 /* bail out on error, */
2081 if (err && err != USBD_IN_PROGRESS)
2082 return (err);
2083
2084 /* XXX should check inuse here */
2085
2086 /* insert into schedule, */
2087 uhci_device_isoc_enter(xfer);
2088
2089 /* and put on interrupt list if the pipe wasn't running */
2090 if (!err)
2091 uhci_device_isoc_start(SIMPLEQ_FIRST(&xfer->pipe->queue));
2092
2093 return (err);
2094 }
2095
2096 void
2097 uhci_device_isoc_enter(xfer)
2098 usbd_xfer_handle xfer;
2099 {
2100 struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
2101 usbd_device_handle dev = upipe->pipe.device;
2102 uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
2103 struct iso *iso = &upipe->u.iso;
2104 uhci_soft_td_t *std;
2105 u_int32_t buf, len, status;
2106 int s, i, next, nframes;
2107
2108 DPRINTFN(5,("uhci_device_isoc_enter: used=%d next=%d xfer=%p "
2109 "nframes=%d\n",
2110 iso->inuse, iso->next, xfer, xfer->nframes));
2111
2112 if (sc->sc_dying)
2113 return;
2114
2115 if (xfer->status == USBD_IN_PROGRESS) {
2116 /* This request has already been entered into the frame list */
2117 /* XXX */
2118 }
2119
2120 #ifdef DIAGNOSTIC
2121 if (iso->inuse >= UHCI_VFRAMELIST_COUNT)
2122 printf("uhci_device_isoc_enter: overflow!\n");
2123 #endif
2124
2125 next = iso->next;
2126 if (next == -1) {
2127 /* Not in use yet, schedule it a few frames ahead. */
2128 next = (UREAD2(sc, UHCI_FRNUM) + 3) % UHCI_VFRAMELIST_COUNT;
2129 DPRINTFN(2,("uhci_device_isoc_enter: start next=%d\n", next));
2130 }
2131
2132 xfer->status = USBD_IN_PROGRESS;
2133 xfer->hcprivint = next;
2134
2135 buf = DMAADDR(&xfer->dmabuf);
2136 status = UHCI_TD_ZERO_ACTLEN(UHCI_TD_SET_ERRCNT(0) |
2137 UHCI_TD_ACTIVE |
2138 UHCI_TD_IOS);
2139 nframes = xfer->nframes;
2140 s = splusb();
2141 for (i = 0; i < nframes; i++) {
2142 std = iso->stds[next];
2143 if (++next >= UHCI_VFRAMELIST_COUNT)
2144 next = 0;
2145 len = xfer->frlengths[i];
2146 std->td.td_buffer = htole32(buf);
2147 if (i == nframes - 1)
2148 status |= UHCI_TD_IOC;
2149 std->td.td_status = htole32(status);
2150 std->td.td_token &= htole32(~UHCI_TD_MAXLEN_MASK);
2151 std->td.td_token |= htole32(UHCI_TD_SET_MAXLEN(len));
2152 #ifdef UHCI_DEBUG
2153 if (uhcidebug > 5) {
2154 DPRINTFN(5,("uhci_device_isoc_enter: TD %d\n", i));
2155 uhci_dump_td(std);
2156 }
2157 #endif
2158 buf += len;
2159 }
2160 iso->next = next;
2161 iso->inuse += xfer->nframes;
2162
2163 splx(s);
2164 }
2165
2166 usbd_status
2167 uhci_device_isoc_start(xfer)
2168 usbd_xfer_handle xfer;
2169 {
2170 struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
2171 uhci_softc_t *sc = (uhci_softc_t *)upipe->pipe.device->bus;
2172 uhci_intr_info_t *ii = upipe->iinfo;
2173 uhci_soft_td_t *end;
2174 int s, i;
2175
2176 if (sc->sc_dying)
2177 return (USBD_IOERROR);
2178
2179 #ifdef DIAGNOSTIC
2180 if (xfer->status != USBD_IN_PROGRESS)
2181 printf("uhci_device_isoc_start: not in progress %p\n", xfer);
2182 #endif
2183
2184 /* Find the last TD */
2185 i = xfer->hcprivint + xfer->nframes;
2186 if (i >= UHCI_VFRAMELIST_COUNT)
2187 i -= UHCI_VFRAMELIST_COUNT;
2188 end = upipe->u.iso.stds[i];
2189
2190 s = splusb();
2191
2192 /* Set up interrupt info. */
2193 ii->xfer = xfer;
2194 ii->stdstart = end;
2195 ii->stdend = end;
2196 #if defined(__FreeBSD__)
2197 callout_handle_init(&ii->timeout_handle);
2198 #endif
2199 #ifdef DIAGNOSTIC
2200 if (!ii->isdone) {
2201 printf("uhci_device_isoc_start: not done, ii=%p\n", ii);
2202 }
2203 ii->isdone = 0;
2204 #endif
2205 LIST_INSERT_HEAD(&sc->sc_intrhead, ii, list);
2206
2207 splx(s);
2208
2209 return (USBD_IN_PROGRESS);
2210 }
2211
2212 void
2213 uhci_device_isoc_abort(xfer)
2214 usbd_xfer_handle xfer;
2215 {
2216 struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
2217 uhci_intr_info_t *ii = upipe->iinfo;
2218 uhci_soft_td_t **stds = upipe->u.iso.stds;
2219 uhci_soft_td_t *std;
2220 int i, n, nframes;
2221
2222 /* Make interrupt routine ignore it, */
2223 xfer->status = USBD_CANCELLED;
2224
2225 /* make hardware ignore it, */
2226 nframes = xfer->nframes;
2227 n = xfer->hcprivint;
2228 for (i = 0; i < nframes; i++) {
2229 std = stds[n];
2230 std->td.td_status &= htole32(~(UHCI_TD_ACTIVE | UHCI_TD_IOC));
2231 if (++n >= UHCI_VFRAMELIST_COUNT)
2232 n = 0;
2233 }
2234
2235 xfer->hcpriv = ii;
2236
2237 /* make sure hardware has completed, */
2238 if (xfer->device->bus->intr_context) {
2239 /* We have no process context, so we can't use tsleep(). */
2240 callout_reset(&xfer->abort_handle, hz / USB_FRAMES_PER_SECOND,
2241 uhci_abort_xfer_end, xfer);
2242 } else {
2243 usb_delay_ms(xfer->pipe->device->bus, 1);
2244 /* and call final part of interrupt handler. */
2245 uhci_abort_xfer_end(xfer);
2246 }
2247 }
2248
2249 void
2250 uhci_device_isoc_close(pipe)
2251 usbd_pipe_handle pipe;
2252 {
2253 struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
2254 usbd_device_handle dev = upipe->pipe.device;
2255 uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
2256 uhci_soft_td_t *std, *vstd;
2257 struct iso *iso;
2258 int i;
2259
2260 /*
2261 * Make sure all TDs are marked as inactive.
2262 * Wait for completion.
2263 * Unschedule.
2264 * Deallocate.
2265 */
2266 iso = &upipe->u.iso;
2267
2268 for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++)
2269 iso->stds[i]->td.td_status &= htole32(~UHCI_TD_ACTIVE);
2270 usb_delay_ms(&sc->sc_bus, 2); /* wait for completion */
2271
2272 uhci_lock_frames(sc);
2273 for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) {
2274 std = iso->stds[i];
2275 for (vstd = sc->sc_vframes[i].htd;
2276 vstd != NULL && vstd->link.std != std;
2277 vstd = vstd->link.std)
2278 ;
2279 if (vstd == NULL) {
2280 /*panic*/
2281 printf("uhci_device_isoc_close: %p not found\n", std);
2282 uhci_unlock_frames(sc);
2283 return;
2284 }
2285 vstd->link = std->link;
2286 vstd->td.td_link = std->td.td_link;
2287 uhci_free_std(sc, std);
2288 }
2289 uhci_unlock_frames(sc);
2290
2291 free(iso->stds, M_USBHC);
2292 }
2293
2294 usbd_status
2295 uhci_setup_isoc(pipe)
2296 usbd_pipe_handle pipe;
2297 {
2298 struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
2299 usbd_device_handle dev = upipe->pipe.device;
2300 uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
2301 int addr = upipe->pipe.device->address;
2302 int endpt = upipe->pipe.endpoint->edesc->bEndpointAddress;
2303 int rd = UE_GET_DIR(endpt) == UE_DIR_IN;
2304 uhci_soft_td_t *std, *vstd;
2305 u_int32_t token;
2306 struct iso *iso;
2307 int i;
2308
2309 iso = &upipe->u.iso;
2310 iso->stds = malloc(UHCI_VFRAMELIST_COUNT * sizeof (uhci_soft_td_t *),
2311 M_USBHC, M_WAITOK);
2312
2313 token = rd ? UHCI_TD_IN (0, endpt, addr, 0) :
2314 UHCI_TD_OUT(0, endpt, addr, 0);
2315
2316 /* Allocate the TDs and mark as inactive; */
2317 for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) {
2318 std = uhci_alloc_std(sc);
2319 if (std == 0)
2320 goto bad;
2321 std->td.td_status = htole32(UHCI_TD_IOS); /* iso, inactive */
2322 std->td.td_token = htole32(token);
2323 iso->stds[i] = std;
2324 }
2325
2326 /* Insert TDs into schedule. */
2327 uhci_lock_frames(sc);
2328 for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) {
2329 std = iso->stds[i];
2330 vstd = sc->sc_vframes[i].htd;
2331 std->link = vstd->link;
2332 std->td.td_link = vstd->td.td_link;
2333 vstd->link.std = std;
2334 vstd->td.td_link = htole32(std->physaddr);
2335 }
2336 uhci_unlock_frames(sc);
2337
2338 iso->next = -1;
2339 iso->inuse = 0;
2340
2341 return (USBD_NORMAL_COMPLETION);
2342
2343 bad:
2344 while (--i >= 0)
2345 uhci_free_std(sc, iso->stds[i]);
2346 free(iso->stds, M_USBHC);
2347 return (USBD_NOMEM);
2348 }
2349
2350 void
2351 uhci_device_isoc_done(xfer)
2352 usbd_xfer_handle xfer;
2353 {
2354 uhci_intr_info_t *ii = xfer->hcpriv;
2355
2356 DPRINTFN(4, ("uhci_isoc_done: length=%d\n", xfer->actlen));
2357
2358 /* Turn off the interrupt since it is active even if the TD is not. */
2359 ii->stdend->td.td_status &= htole32(~UHCI_TD_IOC);
2360
2361 LIST_REMOVE(ii, list); /* remove from active list */
2362 }
2363
2364 void
2365 uhci_device_intr_done(xfer)
2366 usbd_xfer_handle xfer;
2367 {
2368 uhci_intr_info_t *ii = xfer->hcpriv;
2369 uhci_softc_t *sc = ii->sc;
2370 struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
2371 uhci_soft_qh_t *sqh;
2372 int i, npoll;
2373
2374 DPRINTFN(5, ("uhci_intr_done: length=%d\n", xfer->actlen));
2375
2376 npoll = upipe->u.intr.npoll;
2377 for(i = 0; i < npoll; i++) {
2378 sqh = upipe->u.intr.qhs[i];
2379 sqh->elink = 0;
2380 sqh->qh.qh_elink = htole32(UHCI_PTR_T);
2381 }
2382 uhci_free_std_chain(sc, ii->stdstart, 0);
2383
2384 /* XXX Wasteful. */
2385 if (xfer->pipe->repeat) {
2386 uhci_soft_td_t *data, *dataend;
2387
2388 /* This alloc cannot fail since we freed the chain above. */
2389 uhci_alloc_std_chain(upipe, sc, xfer->length, 1, xfer->flags,
2390 &xfer->dmabuf, &data, &dataend);
2391 dataend->td.td_status |= htole32(UHCI_TD_IOC);
2392
2393 #ifdef UHCI_DEBUG
2394 if (uhcidebug > 10) {
2395 DPRINTF(("uhci_device_intr_done: data(1)\n"));
2396 uhci_dump_tds(data);
2397 uhci_dump_qh(upipe->u.intr.qhs[0]);
2398 }
2399 #endif
2400
2401 ii->stdstart = data;
2402 ii->stdend = dataend;
2403 #if defined(__FreeBSD__)
2404 callout_handle_init(&ii->timeout_handle);
2405 #endif
2406 #ifdef DIAGNOSTIC
2407 if (!ii->isdone) {
2408 printf("uhci_device_intr_done: not done, ii=%p\n", ii);
2409 }
2410 ii->isdone = 0;
2411 #endif
2412 for (i = 0; i < npoll; i++) {
2413 sqh = upipe->u.intr.qhs[i];
2414 sqh->elink = data;
2415 sqh->qh.qh_elink = htole32(data->physaddr);
2416 }
2417 } else {
2418 ii->stdstart = 0; /* mark as inactive */
2419 }
2420 }
2421
2422 /* Deallocate request data structures */
2423 void
2424 uhci_device_ctrl_done(xfer)
2425 usbd_xfer_handle xfer;
2426 {
2427 uhci_intr_info_t *ii = xfer->hcpriv;
2428 uhci_softc_t *sc = ii->sc;
2429 struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
2430
2431 #ifdef DIAGNOSTIC
2432 if (!(xfer->rqflags & URQ_REQUEST))
2433 panic("uhci_ctrl_done: not a request\n");
2434 #endif
2435
2436 LIST_REMOVE(ii, list); /* remove from active list */
2437
2438 uhci_remove_ctrl(sc, upipe->u.ctl.sqh);
2439
2440 if (upipe->u.ctl.length != 0)
2441 uhci_free_std_chain(sc, ii->stdstart->link.std, ii->stdend);
2442
2443 DPRINTFN(5, ("uhci_ctrl_done: length=%d\n", xfer->actlen));
2444 }
2445
2446 /* Deallocate request data structures */
2447 void
2448 uhci_device_bulk_done(xfer)
2449 usbd_xfer_handle xfer;
2450 {
2451 uhci_intr_info_t *ii = xfer->hcpriv;
2452 uhci_softc_t *sc = ii->sc;
2453 struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
2454
2455 LIST_REMOVE(ii, list); /* remove from active list */
2456
2457 uhci_remove_bulk(sc, upipe->u.bulk.sqh);
2458
2459 uhci_free_std_chain(sc, ii->stdstart, 0);
2460
2461 DPRINTFN(5, ("uhci_bulk_done: length=%d\n", xfer->actlen));
2462 }
2463
2464 /* Add interrupt QH, called with vflock. */
2465 void
2466 uhci_add_intr(sc, n, sqh)
2467 uhci_softc_t *sc;
2468 int n;
2469 uhci_soft_qh_t *sqh;
2470 {
2471 struct uhci_vframe *vf = &sc->sc_vframes[n];
2472 uhci_soft_qh_t *eqh;
2473
2474 DPRINTFN(4, ("uhci_add_intr: n=%d sqh=%p\n", n, sqh));
2475 eqh = vf->eqh;
2476 sqh->hlink = eqh->hlink;
2477 sqh->qh.qh_hlink = eqh->qh.qh_hlink;
2478 eqh->hlink = sqh;
2479 eqh->qh.qh_hlink = htole32(sqh->physaddr | UHCI_PTR_Q);
2480 vf->eqh = sqh;
2481 vf->bandwidth++;
2482 }
2483
2484 /* Remove interrupt QH, called with vflock. */
2485 void
2486 uhci_remove_intr(sc, n, sqh)
2487 uhci_softc_t *sc;
2488 int n;
2489 uhci_soft_qh_t *sqh;
2490 {
2491 struct uhci_vframe *vf = &sc->sc_vframes[n];
2492 uhci_soft_qh_t *pqh;
2493
2494 DPRINTFN(4, ("uhci_remove_intr: n=%d sqh=%p\n", n, sqh));
2495
2496 for (pqh = vf->hqh; pqh->hlink != sqh; pqh = pqh->hlink)
2497 #if defined(DIAGNOSTIC) || defined(UHCI_DEBUG)
2498 if (le32toh(pqh->qh.qh_hlink) & UHCI_PTR_T) {
2499 DPRINTF(("uhci_remove_intr: QH not found\n"));
2500 return;
2501 }
2502 #else
2503 ;
2504 #endif
2505 pqh->hlink = sqh->hlink;
2506 pqh->qh.qh_hlink = sqh->qh.qh_hlink;
2507 if (vf->eqh == sqh)
2508 vf->eqh = pqh;
2509 vf->bandwidth--;
2510 }
2511
2512 usbd_status
2513 uhci_device_setintr(sc, upipe, ival)
2514 uhci_softc_t *sc;
2515 struct uhci_pipe *upipe;
2516 int ival;
2517 {
2518 uhci_soft_qh_t *sqh;
2519 int i, npoll, s;
2520 u_int bestbw, bw, bestoffs, offs;
2521
2522 DPRINTFN(2, ("uhci_setintr: pipe=%p\n", upipe));
2523 if (ival == 0) {
2524 printf("uhci_setintr: 0 interval\n");
2525 return (USBD_INVAL);
2526 }
2527
2528 if (ival > UHCI_VFRAMELIST_COUNT)
2529 ival = UHCI_VFRAMELIST_COUNT;
2530 npoll = (UHCI_VFRAMELIST_COUNT + ival - 1) / ival;
2531 DPRINTFN(2, ("uhci_setintr: ival=%d npoll=%d\n", ival, npoll));
2532
2533 upipe->u.intr.npoll = npoll;
2534 upipe->u.intr.qhs =
2535 malloc(npoll * sizeof(uhci_soft_qh_t *), M_USBHC, M_WAITOK);
2536
2537 /*
2538 * Figure out which offset in the schedule that has most
2539 * bandwidth left over.
2540 */
2541 #define MOD(i) ((i) & (UHCI_VFRAMELIST_COUNT-1))
2542 for (bestoffs = offs = 0, bestbw = ~0; offs < ival; offs++) {
2543 for (bw = i = 0; i < npoll; i++)
2544 bw += sc->sc_vframes[MOD(i * ival + offs)].bandwidth;
2545 if (bw < bestbw) {
2546 bestbw = bw;
2547 bestoffs = offs;
2548 }
2549 }
2550 DPRINTFN(1, ("uhci_setintr: bw=%d offs=%d\n", bestbw, bestoffs));
2551
2552 upipe->iinfo->stdstart = 0;
2553 for(i = 0; i < npoll; i++) {
2554 upipe->u.intr.qhs[i] = sqh = uhci_alloc_sqh(sc);
2555 sqh->elink = 0;
2556 sqh->qh.qh_elink = htole32(UHCI_PTR_T);
2557 sqh->pos = MOD(i * ival + bestoffs);
2558 sqh->intr_info = upipe->iinfo;
2559 }
2560 #undef MOD
2561
2562 s = splusb();
2563 LIST_INSERT_HEAD(&sc->sc_intrhead, upipe->iinfo, list);
2564 splx(s);
2565
2566 uhci_lock_frames(sc);
2567 /* Enter QHs into the controller data structures. */
2568 for(i = 0; i < npoll; i++)
2569 uhci_add_intr(sc, upipe->u.intr.qhs[i]->pos,
2570 upipe->u.intr.qhs[i]);
2571 uhci_unlock_frames(sc);
2572
2573 DPRINTFN(5, ("uhci_setintr: returns %p\n", upipe));
2574 return (USBD_NORMAL_COMPLETION);
2575 }
2576
2577 /* Open a new pipe. */
2578 usbd_status
2579 uhci_open(pipe)
2580 usbd_pipe_handle pipe;
2581 {
2582 uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus;
2583 struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
2584 usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc;
2585 usbd_status err;
2586 int ival;
2587
2588 DPRINTFN(1, ("uhci_open: pipe=%p, addr=%d, endpt=%d (%d)\n",
2589 pipe, pipe->device->address,
2590 ed->bEndpointAddress, sc->sc_addr));
2591 if (pipe->device->address == sc->sc_addr) {
2592 switch (ed->bEndpointAddress) {
2593 case USB_CONTROL_ENDPOINT:
2594 pipe->methods = &uhci_root_ctrl_methods;
2595 break;
2596 case UE_DIR_IN | UHCI_INTR_ENDPT:
2597 pipe->methods = &uhci_root_intr_methods;
2598 break;
2599 default:
2600 return (USBD_INVAL);
2601 }
2602 } else {
2603 upipe->iinfo = uhci_alloc_intr_info(sc);
2604 if (upipe->iinfo == 0)
2605 return (USBD_NOMEM);
2606 switch (ed->bmAttributes & UE_XFERTYPE) {
2607 case UE_CONTROL:
2608 pipe->methods = &uhci_device_ctrl_methods;
2609 upipe->u.ctl.sqh = uhci_alloc_sqh(sc);
2610 if (upipe->u.ctl.sqh == NULL)
2611 goto bad;
2612 upipe->u.ctl.setup = uhci_alloc_std(sc);
2613 if (upipe->u.ctl.setup == NULL) {
2614 uhci_free_sqh(sc, upipe->u.ctl.sqh);
2615 goto bad;
2616 }
2617 upipe->u.ctl.stat = uhci_alloc_std(sc);
2618 if (upipe->u.ctl.stat == NULL) {
2619 uhci_free_sqh(sc, upipe->u.ctl.sqh);
2620 uhci_free_std(sc, upipe->u.ctl.setup);
2621 goto bad;
2622 }
2623 err = usb_allocmem(&sc->sc_bus,
2624 sizeof(usb_device_request_t),
2625 0, &upipe->u.ctl.reqdma);
2626 if (err) {
2627 uhci_free_sqh(sc, upipe->u.ctl.sqh);
2628 uhci_free_std(sc, upipe->u.ctl.setup);
2629 uhci_free_std(sc, upipe->u.ctl.stat);
2630 goto bad;
2631 }
2632 break;
2633 case UE_INTERRUPT:
2634 pipe->methods = &uhci_device_intr_methods;
2635 ival = pipe->interval;
2636 if (ival == USBD_DEFAULT_INTERVAL)
2637 ival = ed->bInterval;
2638 return (uhci_device_setintr(sc, upipe, ival));
2639 case UE_ISOCHRONOUS:
2640 pipe->methods = &uhci_device_isoc_methods;
2641 return (uhci_setup_isoc(pipe));
2642 case UE_BULK:
2643 pipe->methods = &uhci_device_bulk_methods;
2644 upipe->u.bulk.sqh = uhci_alloc_sqh(sc);
2645 if (upipe->u.bulk.sqh == NULL)
2646 goto bad;
2647 break;
2648 }
2649 }
2650 return (USBD_NORMAL_COMPLETION);
2651
2652 bad:
2653 uhci_free_intr_info(upipe->iinfo);
2654 return (USBD_NOMEM);
2655 }
2656
2657 /*
2658 * Data structures and routines to emulate the root hub.
2659 */
2660 usb_device_descriptor_t uhci_devd = {
2661 USB_DEVICE_DESCRIPTOR_SIZE,
2662 UDESC_DEVICE, /* type */
2663 {0x00, 0x01}, /* USB version */
2664 UDCLASS_HUB, /* class */
2665 UDSUBCLASS_HUB, /* subclass */
2666 0, /* protocol */
2667 64, /* max packet */
2668 {0},{0},{0x00,0x01}, /* device id */
2669 1,2,0, /* string indicies */
2670 1 /* # of configurations */
2671 };
2672
2673 usb_config_descriptor_t uhci_confd = {
2674 USB_CONFIG_DESCRIPTOR_SIZE,
2675 UDESC_CONFIG,
2676 {USB_CONFIG_DESCRIPTOR_SIZE +
2677 USB_INTERFACE_DESCRIPTOR_SIZE +
2678 USB_ENDPOINT_DESCRIPTOR_SIZE},
2679 1,
2680 1,
2681 0,
2682 UC_SELF_POWERED,
2683 0 /* max power */
2684 };
2685
2686 usb_interface_descriptor_t uhci_ifcd = {
2687 USB_INTERFACE_DESCRIPTOR_SIZE,
2688 UDESC_INTERFACE,
2689 0,
2690 0,
2691 1,
2692 UICLASS_HUB,
2693 UISUBCLASS_HUB,
2694 0,
2695 0
2696 };
2697
2698 usb_endpoint_descriptor_t uhci_endpd = {
2699 USB_ENDPOINT_DESCRIPTOR_SIZE,
2700 UDESC_ENDPOINT,
2701 UE_DIR_IN | UHCI_INTR_ENDPT,
2702 UE_INTERRUPT,
2703 {8},
2704 255
2705 };
2706
2707 usb_hub_descriptor_t uhci_hubd_piix = {
2708 USB_HUB_DESCRIPTOR_SIZE,
2709 UDESC_HUB,
2710 2,
2711 { UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL, 0 },
2712 50, /* power on to power good */
2713 0,
2714 { 0x00 }, /* both ports are removable */
2715 };
2716
2717 int
2718 uhci_str(p, l, s)
2719 usb_string_descriptor_t *p;
2720 int l;
2721 char *s;
2722 {
2723 int i;
2724
2725 if (l == 0)
2726 return (0);
2727 p->bLength = 2 * strlen(s) + 2;
2728 if (l == 1)
2729 return (1);
2730 p->bDescriptorType = UDESC_STRING;
2731 l -= 2;
2732 for (i = 0; s[i] && l > 1; i++, l -= 2)
2733 USETW2(p->bString[i], 0, s[i]);
2734 return (2*i+2);
2735 }
2736
2737 /*
2738 * Simulate a hardware hub by handling all the necessary requests.
2739 */
2740 usbd_status
2741 uhci_root_ctrl_transfer(xfer)
2742 usbd_xfer_handle xfer;
2743 {
2744 usbd_status err;
2745
2746 /* Insert last in queue. */
2747 err = usb_insert_transfer(xfer);
2748 if (err)
2749 return (err);
2750
2751 /* Pipe isn't running (otherwise err would be USBD_INPROG),
2752 * start first
2753 */
2754 return (uhci_root_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
2755 }
2756
2757 usbd_status
2758 uhci_root_ctrl_start(xfer)
2759 usbd_xfer_handle xfer;
2760 {
2761 uhci_softc_t *sc = (uhci_softc_t *)xfer->pipe->device->bus;
2762 usb_device_request_t *req;
2763 void *buf = NULL;
2764 int port, x;
2765 int s, len, value, index, status, change, l, totlen = 0;
2766 usb_port_status_t ps;
2767 usbd_status err;
2768
2769 if (sc->sc_dying)
2770 return (USBD_IOERROR);
2771
2772 #ifdef DIAGNOSTIC
2773 if (!(xfer->rqflags & URQ_REQUEST))
2774 panic("uhci_root_ctrl_transfer: not a request\n");
2775 #endif
2776 req = &xfer->request;
2777
2778 DPRINTFN(2,("uhci_root_ctrl_control type=0x%02x request=%02x\n",
2779 req->bmRequestType, req->bRequest));
2780
2781 len = UGETW(req->wLength);
2782 value = UGETW(req->wValue);
2783 index = UGETW(req->wIndex);
2784
2785 if (len != 0)
2786 buf = KERNADDR(&xfer->dmabuf);
2787
2788 #define C(x,y) ((x) | ((y) << 8))
2789 switch(C(req->bRequest, req->bmRequestType)) {
2790 case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE):
2791 case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE):
2792 case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT):
2793 /*
2794 * DEVICE_REMOTE_WAKEUP and ENDPOINT_HALT are no-ops
2795 * for the integrated root hub.
2796 */
2797 break;
2798 case C(UR_GET_CONFIG, UT_READ_DEVICE):
2799 if (len > 0) {
2800 *(u_int8_t *)buf = sc->sc_conf;
2801 totlen = 1;
2802 }
2803 break;
2804 case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
2805 DPRINTFN(2,("uhci_root_ctrl_control wValue=0x%04x\n", value));
2806 switch(value >> 8) {
2807 case UDESC_DEVICE:
2808 if ((value & 0xff) != 0) {
2809 err = USBD_IOERROR;
2810 goto ret;
2811 }
2812 totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE);
2813 USETW(uhci_devd.idVendor, sc->sc_id_vendor);
2814 memcpy(buf, &uhci_devd, l);
2815 break;
2816 case UDESC_CONFIG:
2817 if ((value & 0xff) != 0) {
2818 err = USBD_IOERROR;
2819 goto ret;
2820 }
2821 totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE);
2822 memcpy(buf, &uhci_confd, l);
2823 buf = (char *)buf + l;
2824 len -= l;
2825 l = min(len, USB_INTERFACE_DESCRIPTOR_SIZE);
2826 totlen += l;
2827 memcpy(buf, &uhci_ifcd, l);
2828 buf = (char *)buf + l;
2829 len -= l;
2830 l = min(len, USB_ENDPOINT_DESCRIPTOR_SIZE);
2831 totlen += l;
2832 memcpy(buf, &uhci_endpd, l);
2833 break;
2834 case UDESC_STRING:
2835 if (len == 0)
2836 break;
2837 *(u_int8_t *)buf = 0;
2838 totlen = 1;
2839 switch (value & 0xff) {
2840 case 1: /* Vendor */
2841 totlen = uhci_str(buf, len, sc->sc_vendor);
2842 break;
2843 case 2: /* Product */
2844 totlen = uhci_str(buf, len, "UHCI root hub");
2845 break;
2846 }
2847 break;
2848 default:
2849 err = USBD_IOERROR;
2850 goto ret;
2851 }
2852 break;
2853 case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
2854 if (len > 0) {
2855 *(u_int8_t *)buf = 0;
2856 totlen = 1;
2857 }
2858 break;
2859 case C(UR_GET_STATUS, UT_READ_DEVICE):
2860 if (len > 1) {
2861 USETW(((usb_status_t *)buf)->wStatus,UDS_SELF_POWERED);
2862 totlen = 2;
2863 }
2864 break;
2865 case C(UR_GET_STATUS, UT_READ_INTERFACE):
2866 case C(UR_GET_STATUS, UT_READ_ENDPOINT):
2867 if (len > 1) {
2868 USETW(((usb_status_t *)buf)->wStatus, 0);
2869 totlen = 2;
2870 }
2871 break;
2872 case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
2873 if (value >= USB_MAX_DEVICES) {
2874 err = USBD_IOERROR;
2875 goto ret;
2876 }
2877 sc->sc_addr = value;
2878 break;
2879 case C(UR_SET_CONFIG, UT_WRITE_DEVICE):
2880 if (value != 0 && value != 1) {
2881 err = USBD_IOERROR;
2882 goto ret;
2883 }
2884 sc->sc_conf = value;
2885 break;
2886 case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE):
2887 break;
2888 case C(UR_SET_FEATURE, UT_WRITE_DEVICE):
2889 case C(UR_SET_FEATURE, UT_WRITE_INTERFACE):
2890 case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
2891 err = USBD_IOERROR;
2892 goto ret;
2893 case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
2894 break;
2895 case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT):
2896 break;
2897 /* Hub requests */
2898 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE):
2899 break;
2900 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER):
2901 DPRINTFN(3, ("uhci_root_ctrl_control: UR_CLEAR_PORT_FEATURE "
2902 "port=%d feature=%d\n",
2903 index, value));
2904 if (index == 1)
2905 port = UHCI_PORTSC1;
2906 else if (index == 2)
2907 port = UHCI_PORTSC2;
2908 else {
2909 err = USBD_IOERROR;
2910 goto ret;
2911 }
2912 switch(value) {
2913 case UHF_PORT_ENABLE:
2914 x = UREAD2(sc, port);
2915 UWRITE2(sc, port, x & ~UHCI_PORTSC_PE);
2916 break;
2917 case UHF_PORT_SUSPEND:
2918 x = UREAD2(sc, port);
2919 UWRITE2(sc, port, x & ~UHCI_PORTSC_SUSP);
2920 break;
2921 case UHF_PORT_RESET:
2922 x = UREAD2(sc, port);
2923 UWRITE2(sc, port, x & ~UHCI_PORTSC_PR);
2924 break;
2925 case UHF_C_PORT_CONNECTION:
2926 x = UREAD2(sc, port);
2927 UWRITE2(sc, port, x | UHCI_PORTSC_CSC);
2928 break;
2929 case UHF_C_PORT_ENABLE:
2930 x = UREAD2(sc, port);
2931 UWRITE2(sc, port, x | UHCI_PORTSC_POEDC);
2932 break;
2933 case UHF_C_PORT_OVER_CURRENT:
2934 x = UREAD2(sc, port);
2935 UWRITE2(sc, port, x | UHCI_PORTSC_OCIC);
2936 break;
2937 case UHF_C_PORT_RESET:
2938 sc->sc_isreset = 0;
2939 err = USBD_NORMAL_COMPLETION;
2940 goto ret;
2941 case UHF_PORT_CONNECTION:
2942 case UHF_PORT_OVER_CURRENT:
2943 case UHF_PORT_POWER:
2944 case UHF_PORT_LOW_SPEED:
2945 case UHF_C_PORT_SUSPEND:
2946 default:
2947 err = USBD_IOERROR;
2948 goto ret;
2949 }
2950 break;
2951 case C(UR_GET_BUS_STATE, UT_READ_CLASS_OTHER):
2952 if (index == 1)
2953 port = UHCI_PORTSC1;
2954 else if (index == 2)
2955 port = UHCI_PORTSC2;
2956 else {
2957 err = USBD_IOERROR;
2958 goto ret;
2959 }
2960 if (len > 0) {
2961 *(u_int8_t *)buf =
2962 (UREAD2(sc, port) & UHCI_PORTSC_LS) >>
2963 UHCI_PORTSC_LS_SHIFT;
2964 totlen = 1;
2965 }
2966 break;
2967 case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
2968 if (value != 0) {
2969 err = USBD_IOERROR;
2970 goto ret;
2971 }
2972 l = min(len, USB_HUB_DESCRIPTOR_SIZE);
2973 totlen = l;
2974 memcpy(buf, &uhci_hubd_piix, l);
2975 break;
2976 case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
2977 if (len != 4) {
2978 err = USBD_IOERROR;
2979 goto ret;
2980 }
2981 memset(buf, 0, len);
2982 totlen = len;
2983 break;
2984 case C(UR_GET_STATUS, UT_READ_CLASS_OTHER):
2985 if (index == 1)
2986 port = UHCI_PORTSC1;
2987 else if (index == 2)
2988 port = UHCI_PORTSC2;
2989 else {
2990 err = USBD_IOERROR;
2991 goto ret;
2992 }
2993 if (len != 4) {
2994 err = USBD_IOERROR;
2995 goto ret;
2996 }
2997 x = UREAD2(sc, port);
2998 status = change = 0;
2999 if (x & UHCI_PORTSC_CCS )
3000 status |= UPS_CURRENT_CONNECT_STATUS;
3001 if (x & UHCI_PORTSC_CSC )
3002 change |= UPS_C_CONNECT_STATUS;
3003 if (x & UHCI_PORTSC_PE )
3004 status |= UPS_PORT_ENABLED;
3005 if (x & UHCI_PORTSC_POEDC)
3006 change |= UPS_C_PORT_ENABLED;
3007 if (x & UHCI_PORTSC_OCI )
3008 status |= UPS_OVERCURRENT_INDICATOR;
3009 if (x & UHCI_PORTSC_OCIC )
3010 change |= UPS_C_OVERCURRENT_INDICATOR;
3011 if (x & UHCI_PORTSC_SUSP )
3012 status |= UPS_SUSPEND;
3013 if (x & UHCI_PORTSC_LSDA )
3014 status |= UPS_LOW_SPEED;
3015 status |= UPS_PORT_POWER;
3016 if (sc->sc_isreset)
3017 change |= UPS_C_PORT_RESET;
3018 USETW(ps.wPortStatus, status);
3019 USETW(ps.wPortChange, change);
3020 l = min(len, sizeof ps);
3021 memcpy(buf, &ps, l);
3022 totlen = l;
3023 break;
3024 case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
3025 err = USBD_IOERROR;
3026 goto ret;
3027 case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE):
3028 break;
3029 case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER):
3030 if (index == 1)
3031 port = UHCI_PORTSC1;
3032 else if (index == 2)
3033 port = UHCI_PORTSC2;
3034 else {
3035 err = USBD_IOERROR;
3036 goto ret;
3037 }
3038 switch(value) {
3039 case UHF_PORT_ENABLE:
3040 x = UREAD2(sc, port);
3041 UWRITE2(sc, port, x | UHCI_PORTSC_PE);
3042 break;
3043 case UHF_PORT_SUSPEND:
3044 x = UREAD2(sc, port);
3045 UWRITE2(sc, port, x | UHCI_PORTSC_SUSP);
3046 break;
3047 case UHF_PORT_RESET:
3048 x = UREAD2(sc, port);
3049 UWRITE2(sc, port, x | UHCI_PORTSC_PR);
3050 usb_delay_ms(&sc->sc_bus, 10);
3051 UWRITE2(sc, port, x & ~UHCI_PORTSC_PR);
3052 delay(100);
3053 x = UREAD2(sc, port);
3054 UWRITE2(sc, port, x | UHCI_PORTSC_PE);
3055 delay(100);
3056 DPRINTFN(3,("uhci port %d reset, status = 0x%04x\n",
3057 index, UREAD2(sc, port)));
3058 sc->sc_isreset = 1;
3059 break;
3060 case UHF_C_PORT_CONNECTION:
3061 case UHF_C_PORT_ENABLE:
3062 case UHF_C_PORT_OVER_CURRENT:
3063 case UHF_PORT_CONNECTION:
3064 case UHF_PORT_OVER_CURRENT:
3065 case UHF_PORT_POWER:
3066 case UHF_PORT_LOW_SPEED:
3067 case UHF_C_PORT_SUSPEND:
3068 case UHF_C_PORT_RESET:
3069 default:
3070 err = USBD_IOERROR;
3071 goto ret;
3072 }
3073 break;
3074 default:
3075 err = USBD_IOERROR;
3076 goto ret;
3077 }
3078 xfer->actlen = totlen;
3079 err = USBD_NORMAL_COMPLETION;
3080 ret:
3081 xfer->status = err;
3082 xfer->hcpriv = 0;
3083 s = splusb();
3084 usb_transfer_complete(xfer);
3085 splx(s);
3086 return (USBD_IN_PROGRESS);
3087 }
3088
3089 /* Abort a root control request. */
3090 void
3091 uhci_root_ctrl_abort(xfer)
3092 usbd_xfer_handle xfer;
3093 {
3094 /* Nothing to do, all transfers are synchronous. */
3095 }
3096
3097 /* Close the root pipe. */
3098 void
3099 uhci_root_ctrl_close(pipe)
3100 usbd_pipe_handle pipe;
3101 {
3102 DPRINTF(("uhci_root_ctrl_close\n"));
3103 }
3104
3105 /* Abort a root interrupt request. */
3106 void
3107 uhci_root_intr_abort(xfer)
3108 usbd_xfer_handle xfer;
3109 {
3110 uhci_softc_t *sc = (uhci_softc_t *)xfer->pipe->device->bus;
3111
3112 usb_untimeout(uhci_timo, xfer, xfer->timo_handle);
3113 sc->sc_has_timo = NULL;
3114
3115 if (xfer->pipe->intrxfer == xfer) {
3116 DPRINTF(("uhci_root_intr_abort: remove\n"));
3117 xfer->pipe->intrxfer = 0;
3118 }
3119 xfer->status = USBD_CANCELLED;
3120 usb_transfer_complete(xfer);
3121 }
3122
3123 usbd_status
3124 uhci_root_intr_transfer(xfer)
3125 usbd_xfer_handle xfer;
3126 {
3127 usbd_status err;
3128
3129 /* Insert last in queue. */
3130 err = usb_insert_transfer(xfer);
3131 if (err)
3132 return (err);
3133
3134 /* Pipe isn't running (otherwise err would be USBD_INPROG),
3135 * start first
3136 */
3137 return (uhci_root_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
3138 }
3139
3140 /* Start a transfer on the root interrupt pipe */
3141 usbd_status
3142 uhci_root_intr_start(xfer)
3143 usbd_xfer_handle xfer;
3144 {
3145 usbd_pipe_handle pipe = xfer->pipe;
3146 uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus;
3147
3148 DPRINTFN(3, ("uhci_root_intr_transfer: xfer=%p len=%d flags=%d\n",
3149 xfer, xfer->length, xfer->flags));
3150
3151 if (sc->sc_dying)
3152 return (USBD_IOERROR);
3153
3154 sc->sc_ival = MS_TO_TICKS(xfer->pipe->endpoint->edesc->bInterval);
3155 usb_timeout(uhci_timo, xfer, sc->sc_ival, xfer->timo_handle);
3156 sc->sc_has_timo = xfer;
3157 return (USBD_IN_PROGRESS);
3158 }
3159
3160 /* Close the root interrupt pipe. */
3161 void
3162 uhci_root_intr_close(pipe)
3163 usbd_pipe_handle pipe;
3164 {
3165 uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus;
3166
3167 usb_untimeout(uhci_timo, pipe->intrxfer, pipe->intrxfer->timo_handle);
3168 sc->sc_has_timo = NULL;
3169 DPRINTF(("uhci_root_intr_close\n"));
3170 }
3171