uhci.c revision 1.88 1 /* $NetBSD: uhci.c,v 1.88 2000/03/16 12:40:51 tsutsui 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 timeout(uhci_abort_xfer_end, xfer, hz / USB_FRAMES_PER_SECOND);
1696 } else {
1697 #if defined(DIAGNOSTIC) && defined(__i386__) && defined(__FreeBSD__)
1698 KASSERT(intr_nesting_level == 0,
1699 ("ohci_abort_req in interrupt context"));
1700 #endif
1701 usb_delay_ms(xfer->pipe->device->bus, 1);
1702 /* and call final part of interrupt handler. */
1703 uhci_abort_xfer_end(xfer);
1704 }
1705 #else
1706 delay(1000);
1707 uhci_abort_xfer_end(xfer);
1708 #endif
1709 }
1710
1711 void
1712 uhci_abort_xfer_end(v)
1713 void *v;
1714 {
1715 usbd_xfer_handle xfer = v;
1716 int s;
1717
1718 s = splusb();
1719 usb_transfer_complete(xfer);
1720 splx(s);
1721 }
1722
1723 /* Close a device bulk pipe. */
1724 void
1725 uhci_device_bulk_close(pipe)
1726 usbd_pipe_handle pipe;
1727 {
1728 struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
1729 usbd_device_handle dev = upipe->pipe.device;
1730 uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
1731
1732 uhci_free_sqh(sc, upipe->u.bulk.sqh);
1733 uhci_free_intr_info(upipe->iinfo);
1734 /* XXX free other resources */
1735 }
1736
1737 usbd_status
1738 uhci_device_ctrl_transfer(xfer)
1739 usbd_xfer_handle xfer;
1740 {
1741 usbd_status err;
1742
1743 /* Insert last in queue. */
1744 err = usb_insert_transfer(xfer);
1745 if (err)
1746 return (err);
1747
1748 /* Pipe isn't running (otherwise err would be USBD_INPROG),
1749 * start first
1750 */
1751 return (uhci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
1752 }
1753
1754 usbd_status
1755 uhci_device_ctrl_start(xfer)
1756 usbd_xfer_handle xfer;
1757 {
1758 uhci_softc_t *sc = (uhci_softc_t *)xfer->pipe->device->bus;
1759 usbd_status err;
1760
1761 if (sc->sc_dying)
1762 return (USBD_IOERROR);
1763
1764 #ifdef DIAGNOSTIC
1765 if (!(xfer->rqflags & URQ_REQUEST))
1766 panic("uhci_device_ctrl_transfer: not a request\n");
1767 #endif
1768
1769 err = uhci_device_request(xfer);
1770 if (err)
1771 return (err);
1772
1773 if (sc->sc_bus.use_polling)
1774 uhci_waitintr(sc, xfer);
1775 return (USBD_IN_PROGRESS);
1776 }
1777
1778 usbd_status
1779 uhci_device_intr_transfer(xfer)
1780 usbd_xfer_handle xfer;
1781 {
1782 usbd_status err;
1783
1784 /* Insert last in queue. */
1785 err = usb_insert_transfer(xfer);
1786 if (err)
1787 return (err);
1788
1789 /* Pipe isn't running (otherwise err would be USBD_INPROG),
1790 * start first
1791 */
1792 return (uhci_device_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
1793 }
1794
1795 usbd_status
1796 uhci_device_intr_start(xfer)
1797 usbd_xfer_handle xfer;
1798 {
1799 struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
1800 usbd_device_handle dev = upipe->pipe.device;
1801 uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
1802 uhci_intr_info_t *ii = upipe->iinfo;
1803 uhci_soft_td_t *data, *dataend;
1804 uhci_soft_qh_t *sqh;
1805 usbd_status err;
1806 int i, s;
1807
1808 if (sc->sc_dying)
1809 return (USBD_IOERROR);
1810
1811 DPRINTFN(3,("uhci_device_intr_transfer: xfer=%p len=%d flags=%d\n",
1812 xfer, xfer->length, xfer->flags));
1813
1814 #ifdef DIAGNOSTIC
1815 if (xfer->rqflags & URQ_REQUEST)
1816 panic("uhci_device_intr_transfer: a request\n");
1817 #endif
1818
1819 err = uhci_alloc_std_chain(upipe, sc, xfer->length, 1, xfer->flags,
1820 &xfer->dmabuf, &data, &dataend);
1821 if (err)
1822 return (err);
1823 dataend->td.td_status |= htole32(UHCI_TD_IOC);
1824
1825 #ifdef UHCI_DEBUG
1826 if (uhcidebug > 10) {
1827 DPRINTF(("uhci_device_intr_transfer: data(1)\n"));
1828 uhci_dump_tds(data);
1829 uhci_dump_qh(upipe->u.intr.qhs[0]);
1830 }
1831 #endif
1832
1833 s = splusb();
1834 /* Set up interrupt info. */
1835 ii->xfer = xfer;
1836 ii->stdstart = data;
1837 ii->stdend = dataend;
1838 #if defined(__FreeBSD__)
1839 callout_handle_init(&ii->timeout_handle);
1840 #endif
1841 #ifdef DIAGNOSTIC
1842 if (!ii->isdone) {
1843 printf("uhci_device_intr_transfer: not done, ii=%p\n", ii);
1844 }
1845 ii->isdone = 0;
1846 #endif
1847
1848 DPRINTFN(10,("uhci_device_intr_transfer: qhs[0]=%p\n",
1849 upipe->u.intr.qhs[0]));
1850 for (i = 0; i < upipe->u.intr.npoll; i++) {
1851 sqh = upipe->u.intr.qhs[i];
1852 sqh->elink = data;
1853 sqh->qh.qh_elink = htole32(data->physaddr);
1854 }
1855 splx(s);
1856
1857 #ifdef UHCI_DEBUG
1858 if (uhcidebug > 10) {
1859 DPRINTF(("uhci_device_intr_transfer: data(2)\n"));
1860 uhci_dump_tds(data);
1861 uhci_dump_qh(upipe->u.intr.qhs[0]);
1862 }
1863 #endif
1864
1865 return (USBD_IN_PROGRESS);
1866 }
1867
1868 /* Abort a device control request. */
1869 void
1870 uhci_device_ctrl_abort(xfer)
1871 usbd_xfer_handle xfer;
1872 {
1873 DPRINTF(("uhci_device_ctrl_abort:\n"));
1874 uhci_abort_xfer(xfer, USBD_CANCELLED);
1875 }
1876
1877 /* Close a device control pipe. */
1878 void
1879 uhci_device_ctrl_close(pipe)
1880 usbd_pipe_handle pipe;
1881 {
1882 struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
1883
1884 uhci_free_intr_info(upipe->iinfo);
1885 /* XXX free other resources? */
1886 }
1887
1888 /* Abort a device interrupt request. */
1889 void
1890 uhci_device_intr_abort(xfer)
1891 usbd_xfer_handle xfer;
1892 {
1893 DPRINTFN(1,("uhci_device_intr_abort: xfer=%p\n", xfer));
1894 if (xfer->pipe->intrxfer == xfer) {
1895 DPRINTFN(1,("uhci_device_intr_abort: remove\n"));
1896 xfer->pipe->intrxfer = 0;
1897 }
1898 uhci_abort_xfer(xfer, USBD_CANCELLED);
1899 }
1900
1901 /* Close a device interrupt pipe. */
1902 void
1903 uhci_device_intr_close(pipe)
1904 usbd_pipe_handle pipe;
1905 {
1906 struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
1907 uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus;
1908 int i, s, npoll;
1909
1910 upipe->iinfo->stdstart = 0; /* inactive */
1911
1912 /* Unlink descriptors from controller data structures. */
1913 npoll = upipe->u.intr.npoll;
1914 uhci_lock_frames(sc);
1915 for (i = 0; i < npoll; i++)
1916 uhci_remove_intr(sc, upipe->u.intr.qhs[i]->pos,
1917 upipe->u.intr.qhs[i]);
1918 uhci_unlock_frames(sc);
1919
1920 /*
1921 * We now have to wait for any activity on the physical
1922 * descriptors to stop.
1923 */
1924 usb_delay_ms(&sc->sc_bus, 2);
1925
1926 for(i = 0; i < npoll; i++)
1927 uhci_free_sqh(sc, upipe->u.intr.qhs[i]);
1928 free(upipe->u.intr.qhs, M_USBHC);
1929
1930 s = splusb();
1931 LIST_REMOVE(upipe->iinfo, list); /* remove from active list */
1932 splx(s);
1933 uhci_free_intr_info(upipe->iinfo);
1934
1935 /* XXX free other resources */
1936 }
1937
1938 usbd_status
1939 uhci_device_request(xfer)
1940 usbd_xfer_handle xfer;
1941 {
1942 struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
1943 usb_device_request_t *req = &xfer->request;
1944 usbd_device_handle dev = upipe->pipe.device;
1945 uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
1946 int addr = dev->address;
1947 int endpt = upipe->pipe.endpoint->edesc->bEndpointAddress;
1948 uhci_intr_info_t *ii = upipe->iinfo;
1949 uhci_soft_td_t *setup, *data, *stat, *next, *dataend;
1950 uhci_soft_qh_t *sqh;
1951 int len;
1952 u_int32_t ls;
1953 usbd_status err;
1954 int isread;
1955 int s;
1956
1957 DPRINTFN(3,("uhci_device_control type=0x%02x, request=0x%02x, "
1958 "wValue=0x%04x, wIndex=0x%04x len=%d, addr=%d, endpt=%d\n",
1959 req->bmRequestType, req->bRequest, UGETW(req->wValue),
1960 UGETW(req->wIndex), UGETW(req->wLength),
1961 addr, endpt));
1962
1963 ls = dev->lowspeed ? UHCI_TD_LS : 0;
1964 isread = req->bmRequestType & UT_READ;
1965 len = UGETW(req->wLength);
1966
1967 setup = upipe->u.ctl.setup;
1968 stat = upipe->u.ctl.stat;
1969 sqh = upipe->u.ctl.sqh;
1970
1971 /* Set up data transaction */
1972 if (len != 0) {
1973 upipe->nexttoggle = 1;
1974 err = uhci_alloc_std_chain(upipe, sc, len, isread, xfer->flags,
1975 &xfer->dmabuf, &data, &dataend);
1976 if (err)
1977 return (err);
1978 next = data;
1979 dataend->link.std = stat;
1980 dataend->td.td_link = htole32(stat->physaddr | UHCI_PTR_VF);
1981 } else {
1982 next = stat;
1983 }
1984 upipe->u.ctl.length = len;
1985
1986 memcpy(KERNADDR(&upipe->u.ctl.reqdma), req, sizeof *req);
1987
1988 setup->link.std = next;
1989 setup->td.td_link = htole32(next->physaddr | UHCI_PTR_VF);
1990 setup->td.td_status = htole32(UHCI_TD_SET_ERRCNT(3) | ls |
1991 UHCI_TD_ACTIVE);
1992 setup->td.td_token = htole32(UHCI_TD_SETUP(sizeof *req, endpt, addr));
1993 setup->td.td_buffer = htole32(DMAADDR(&upipe->u.ctl.reqdma));
1994
1995 stat->link.std = 0;
1996 stat->td.td_link = htole32(UHCI_PTR_T);
1997 stat->td.td_status = htole32(UHCI_TD_SET_ERRCNT(3) | ls |
1998 UHCI_TD_ACTIVE | UHCI_TD_IOC);
1999 stat->td.td_token =
2000 htole32(isread ? UHCI_TD_OUT(0, endpt, addr, 1) :
2001 UHCI_TD_IN (0, endpt, addr, 1));
2002 stat->td.td_buffer = htole32(0);
2003
2004 #ifdef UHCI_DEBUG
2005 if (uhcidebug > 10) {
2006 DPRINTF(("uhci_device_request: before transfer\n"));
2007 uhci_dump_tds(setup);
2008 }
2009 #endif
2010
2011 /* Set up interrupt info. */
2012 ii->xfer = xfer;
2013 ii->stdstart = setup;
2014 ii->stdend = stat;
2015 #if defined(__FreeBSD__)
2016 callout_handle_init(&ii->timeout_handle);
2017 #endif
2018 #ifdef DIAGNOSTIC
2019 if (!ii->isdone) {
2020 printf("uhci_device_request: not done, ii=%p\n", ii);
2021 }
2022 ii->isdone = 0;
2023 #endif
2024
2025 sqh->elink = setup;
2026 sqh->qh.qh_elink = htole32(setup->physaddr);
2027 sqh->intr_info = ii;
2028
2029 s = splusb();
2030 uhci_add_ctrl(sc, sqh);
2031 LIST_INSERT_HEAD(&sc->sc_intrhead, ii, list);
2032 #ifdef UHCI_DEBUG
2033 if (uhcidebug > 12) {
2034 uhci_soft_td_t *std;
2035 uhci_soft_qh_t *xqh;
2036 uhci_soft_qh_t *sxqh;
2037 int maxqh = 0;
2038 uhci_physaddr_t link;
2039 DPRINTF(("uhci_enter_ctl_q: follow from [0]\n"));
2040 for (std = sc->sc_vframes[0].htd, link = 0;
2041 (link & UHCI_PTR_Q) == 0;
2042 std = std->link.std) {
2043 link = le32toh(std->td.td_link);
2044 uhci_dump_td(std);
2045 }
2046 sxqh = (uhci_soft_qh_t *)std;
2047 uhci_dump_qh(sxqh);
2048 for (xqh = sxqh;
2049 xqh != NULL;
2050 xqh = (maxqh++ == 5 || xqh->hlink==sxqh ||
2051 xqh->hlink==xqh ? NULL : xqh->hlink)) {
2052 uhci_dump_qh(xqh);
2053 }
2054 DPRINTF(("Enqueued QH:\n"));
2055 uhci_dump_qh(sqh);
2056 uhci_dump_tds(sqh->elink);
2057 }
2058 #endif
2059 if (xfer->timeout && !sc->sc_bus.use_polling) {
2060 usb_timeout(uhci_timeout, ii,
2061 MS_TO_TICKS(xfer->timeout), ii->timeout_handle);
2062 }
2063 splx(s);
2064
2065 return (USBD_NORMAL_COMPLETION);
2066 }
2067
2068 usbd_status
2069 uhci_device_isoc_transfer(xfer)
2070 usbd_xfer_handle xfer;
2071 {
2072 usbd_status err;
2073
2074 DPRINTFN(5,("uhci_device_isoc_transfer: xfer=%p\n", xfer));
2075
2076 /* Put it on our queue, */
2077 err = usb_insert_transfer(xfer);
2078
2079 /* bail out on error, */
2080 if (err && err != USBD_IN_PROGRESS)
2081 return (err);
2082
2083 /* XXX should check inuse here */
2084
2085 /* insert into schedule, */
2086 uhci_device_isoc_enter(xfer);
2087
2088 /* and put on interrupt list if the pipe wasn't running */
2089 if (!err)
2090 uhci_device_isoc_start(SIMPLEQ_FIRST(&xfer->pipe->queue));
2091
2092 return (err);
2093 }
2094
2095 void
2096 uhci_device_isoc_enter(xfer)
2097 usbd_xfer_handle xfer;
2098 {
2099 struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
2100 usbd_device_handle dev = upipe->pipe.device;
2101 uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
2102 struct iso *iso = &upipe->u.iso;
2103 uhci_soft_td_t *std;
2104 u_int32_t buf, len, status;
2105 int s, i, next, nframes;
2106
2107 DPRINTFN(5,("uhci_device_isoc_enter: used=%d next=%d xfer=%p "
2108 "nframes=%d\n",
2109 iso->inuse, iso->next, xfer, xfer->nframes));
2110
2111 if (sc->sc_dying)
2112 return;
2113
2114 if (xfer->status == USBD_IN_PROGRESS) {
2115 /* This request has already been entered into the frame list */
2116 /* XXX */
2117 }
2118
2119 #ifdef DIAGNOSTIC
2120 if (iso->inuse >= UHCI_VFRAMELIST_COUNT)
2121 printf("uhci_device_isoc_enter: overflow!\n");
2122 #endif
2123
2124 next = iso->next;
2125 if (next == -1) {
2126 /* Not in use yet, schedule it a few frames ahead. */
2127 next = (UREAD2(sc, UHCI_FRNUM) + 3) % UHCI_VFRAMELIST_COUNT;
2128 DPRINTFN(2,("uhci_device_isoc_enter: start next=%d\n", next));
2129 }
2130
2131 xfer->status = USBD_IN_PROGRESS;
2132 xfer->hcprivint = next;
2133
2134 buf = DMAADDR(&xfer->dmabuf);
2135 status = UHCI_TD_ZERO_ACTLEN(UHCI_TD_SET_ERRCNT(0) |
2136 UHCI_TD_ACTIVE |
2137 UHCI_TD_IOS);
2138 nframes = xfer->nframes;
2139 s = splusb();
2140 for (i = 0; i < nframes; i++) {
2141 std = iso->stds[next];
2142 if (++next >= UHCI_VFRAMELIST_COUNT)
2143 next = 0;
2144 len = xfer->frlengths[i];
2145 std->td.td_buffer = htole32(buf);
2146 if (i == nframes - 1)
2147 status |= UHCI_TD_IOC;
2148 std->td.td_status = htole32(status);
2149 std->td.td_token &= htole32(~UHCI_TD_MAXLEN_MASK);
2150 std->td.td_token |= htole32(UHCI_TD_SET_MAXLEN(len));
2151 #ifdef UHCI_DEBUG
2152 if (uhcidebug > 5) {
2153 DPRINTFN(5,("uhci_device_isoc_enter: TD %d\n", i));
2154 uhci_dump_td(std);
2155 }
2156 #endif
2157 buf += len;
2158 }
2159 iso->next = next;
2160 iso->inuse += xfer->nframes;
2161
2162 splx(s);
2163 }
2164
2165 usbd_status
2166 uhci_device_isoc_start(xfer)
2167 usbd_xfer_handle xfer;
2168 {
2169 struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
2170 uhci_softc_t *sc = (uhci_softc_t *)upipe->pipe.device->bus;
2171 uhci_intr_info_t *ii = upipe->iinfo;
2172 uhci_soft_td_t *end;
2173 int s, i;
2174
2175 if (sc->sc_dying)
2176 return (USBD_IOERROR);
2177
2178 #ifdef DIAGNOSTIC
2179 if (xfer->status != USBD_IN_PROGRESS)
2180 printf("uhci_device_isoc_start: not in progress %p\n", xfer);
2181 #endif
2182
2183 /* Find the last TD */
2184 i = xfer->hcprivint + xfer->nframes;
2185 if (i >= UHCI_VFRAMELIST_COUNT)
2186 i -= UHCI_VFRAMELIST_COUNT;
2187 end = upipe->u.iso.stds[i];
2188
2189 s = splusb();
2190
2191 /* Set up interrupt info. */
2192 ii->xfer = xfer;
2193 ii->stdstart = end;
2194 ii->stdend = end;
2195 #if defined(__FreeBSD__)
2196 callout_handle_init(&ii->timeout_handle);
2197 #endif
2198 #ifdef DIAGNOSTIC
2199 if (!ii->isdone) {
2200 printf("uhci_device_isoc_start: not done, ii=%p\n", ii);
2201 }
2202 ii->isdone = 0;
2203 #endif
2204 LIST_INSERT_HEAD(&sc->sc_intrhead, ii, list);
2205
2206 splx(s);
2207
2208 return (USBD_IN_PROGRESS);
2209 }
2210
2211 void
2212 uhci_device_isoc_abort(xfer)
2213 usbd_xfer_handle xfer;
2214 {
2215 struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
2216 uhci_intr_info_t *ii = upipe->iinfo;
2217 uhci_soft_td_t **stds = upipe->u.iso.stds;
2218 uhci_soft_td_t *std;
2219 int i, n, nframes;
2220
2221 /* Make interrupt routine ignore it, */
2222 xfer->status = USBD_CANCELLED;
2223
2224 /* make hardware ignore it, */
2225 nframes = xfer->nframes;
2226 n = xfer->hcprivint;
2227 for (i = 0; i < nframes; i++) {
2228 std = stds[n];
2229 std->td.td_status &= htole32(~(UHCI_TD_ACTIVE | UHCI_TD_IOC));
2230 if (++n >= UHCI_VFRAMELIST_COUNT)
2231 n = 0;
2232 }
2233
2234 xfer->hcpriv = ii;
2235
2236 /* make sure hardware has completed, */
2237 if (xfer->device->bus->intr_context) {
2238 /* We have no process context, so we can't use tsleep(). */
2239 timeout(uhci_abort_xfer_end, xfer, hz / USB_FRAMES_PER_SECOND);
2240 } else {
2241 usb_delay_ms(xfer->pipe->device->bus, 1);
2242 /* and call final part of interrupt handler. */
2243 uhci_abort_xfer_end(xfer);
2244 }
2245 }
2246
2247 void
2248 uhci_device_isoc_close(pipe)
2249 usbd_pipe_handle pipe;
2250 {
2251 struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
2252 usbd_device_handle dev = upipe->pipe.device;
2253 uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
2254 uhci_soft_td_t *std, *vstd;
2255 struct iso *iso;
2256 int i;
2257
2258 /*
2259 * Make sure all TDs are marked as inactive.
2260 * Wait for completion.
2261 * Unschedule.
2262 * Deallocate.
2263 */
2264 iso = &upipe->u.iso;
2265
2266 for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++)
2267 iso->stds[i]->td.td_status &= htole32(~UHCI_TD_ACTIVE);
2268 usb_delay_ms(&sc->sc_bus, 2); /* wait for completion */
2269
2270 uhci_lock_frames(sc);
2271 for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) {
2272 std = iso->stds[i];
2273 for (vstd = sc->sc_vframes[i].htd;
2274 vstd != NULL && vstd->link.std != std;
2275 vstd = vstd->link.std)
2276 ;
2277 if (vstd == NULL) {
2278 /*panic*/
2279 printf("uhci_device_isoc_close: %p not found\n", std);
2280 uhci_unlock_frames(sc);
2281 return;
2282 }
2283 vstd->link = std->link;
2284 vstd->td.td_link = std->td.td_link;
2285 uhci_free_std(sc, std);
2286 }
2287 uhci_unlock_frames(sc);
2288
2289 free(iso->stds, M_USBHC);
2290 }
2291
2292 usbd_status
2293 uhci_setup_isoc(pipe)
2294 usbd_pipe_handle pipe;
2295 {
2296 struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
2297 usbd_device_handle dev = upipe->pipe.device;
2298 uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
2299 int addr = upipe->pipe.device->address;
2300 int endpt = upipe->pipe.endpoint->edesc->bEndpointAddress;
2301 int rd = UE_GET_DIR(endpt) == UE_DIR_IN;
2302 uhci_soft_td_t *std, *vstd;
2303 u_int32_t token;
2304 struct iso *iso;
2305 int i;
2306
2307 iso = &upipe->u.iso;
2308 iso->stds = malloc(UHCI_VFRAMELIST_COUNT * sizeof (uhci_soft_td_t *),
2309 M_USBHC, M_WAITOK);
2310
2311 token = rd ? UHCI_TD_IN (0, endpt, addr, 0) :
2312 UHCI_TD_OUT(0, endpt, addr, 0);
2313
2314 /* Allocate the TDs and mark as inactive; */
2315 for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) {
2316 std = uhci_alloc_std(sc);
2317 if (std == 0)
2318 goto bad;
2319 std->td.td_status = htole32(UHCI_TD_IOS); /* iso, inactive */
2320 std->td.td_token = htole32(token);
2321 iso->stds[i] = std;
2322 }
2323
2324 /* Insert TDs into schedule. */
2325 uhci_lock_frames(sc);
2326 for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) {
2327 std = iso->stds[i];
2328 vstd = sc->sc_vframes[i].htd;
2329 std->link = vstd->link;
2330 std->td.td_link = vstd->td.td_link;
2331 vstd->link.std = std;
2332 vstd->td.td_link = htole32(std->physaddr);
2333 }
2334 uhci_unlock_frames(sc);
2335
2336 iso->next = -1;
2337 iso->inuse = 0;
2338
2339 return (USBD_NORMAL_COMPLETION);
2340
2341 bad:
2342 while (--i >= 0)
2343 uhci_free_std(sc, iso->stds[i]);
2344 free(iso->stds, M_USBHC);
2345 return (USBD_NOMEM);
2346 }
2347
2348 void
2349 uhci_device_isoc_done(xfer)
2350 usbd_xfer_handle xfer;
2351 {
2352 uhci_intr_info_t *ii = xfer->hcpriv;
2353
2354 DPRINTFN(4, ("uhci_isoc_done: length=%d\n", xfer->actlen));
2355
2356 /* Turn off the interrupt since it is active even if the TD is not. */
2357 ii->stdend->td.td_status &= htole32(~UHCI_TD_IOC);
2358
2359 LIST_REMOVE(ii, list); /* remove from active list */
2360 }
2361
2362 void
2363 uhci_device_intr_done(xfer)
2364 usbd_xfer_handle xfer;
2365 {
2366 uhci_intr_info_t *ii = xfer->hcpriv;
2367 uhci_softc_t *sc = ii->sc;
2368 struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
2369 uhci_soft_qh_t *sqh;
2370 int i, npoll;
2371
2372 DPRINTFN(5, ("uhci_intr_done: length=%d\n", xfer->actlen));
2373
2374 npoll = upipe->u.intr.npoll;
2375 for(i = 0; i < npoll; i++) {
2376 sqh = upipe->u.intr.qhs[i];
2377 sqh->elink = 0;
2378 sqh->qh.qh_elink = htole32(UHCI_PTR_T);
2379 }
2380 uhci_free_std_chain(sc, ii->stdstart, 0);
2381
2382 /* XXX Wasteful. */
2383 if (xfer->pipe->repeat) {
2384 uhci_soft_td_t *data, *dataend;
2385
2386 /* This alloc cannot fail since we freed the chain above. */
2387 uhci_alloc_std_chain(upipe, sc, xfer->length, 1, xfer->flags,
2388 &xfer->dmabuf, &data, &dataend);
2389 dataend->td.td_status |= htole32(UHCI_TD_IOC);
2390
2391 #ifdef UHCI_DEBUG
2392 if (uhcidebug > 10) {
2393 DPRINTF(("uhci_device_intr_done: data(1)\n"));
2394 uhci_dump_tds(data);
2395 uhci_dump_qh(upipe->u.intr.qhs[0]);
2396 }
2397 #endif
2398
2399 ii->stdstart = data;
2400 ii->stdend = dataend;
2401 #if defined(__FreeBSD__)
2402 callout_handle_init(&ii->timeout_handle);
2403 #endif
2404 #ifdef DIAGNOSTIC
2405 if (!ii->isdone) {
2406 printf("uhci_device_intr_done: not done, ii=%p\n", ii);
2407 }
2408 ii->isdone = 0;
2409 #endif
2410 for (i = 0; i < npoll; i++) {
2411 sqh = upipe->u.intr.qhs[i];
2412 sqh->elink = data;
2413 sqh->qh.qh_elink = htole32(data->physaddr);
2414 }
2415 } else {
2416 ii->stdstart = 0; /* mark as inactive */
2417 }
2418 }
2419
2420 /* Deallocate request data structures */
2421 void
2422 uhci_device_ctrl_done(xfer)
2423 usbd_xfer_handle xfer;
2424 {
2425 uhci_intr_info_t *ii = xfer->hcpriv;
2426 uhci_softc_t *sc = ii->sc;
2427 struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
2428
2429 #ifdef DIAGNOSTIC
2430 if (!(xfer->rqflags & URQ_REQUEST))
2431 panic("uhci_ctrl_done: not a request\n");
2432 #endif
2433
2434 LIST_REMOVE(ii, list); /* remove from active list */
2435
2436 uhci_remove_ctrl(sc, upipe->u.ctl.sqh);
2437
2438 if (upipe->u.ctl.length != 0)
2439 uhci_free_std_chain(sc, ii->stdstart->link.std, ii->stdend);
2440
2441 DPRINTFN(5, ("uhci_ctrl_done: length=%d\n", xfer->actlen));
2442 }
2443
2444 /* Deallocate request data structures */
2445 void
2446 uhci_device_bulk_done(xfer)
2447 usbd_xfer_handle xfer;
2448 {
2449 uhci_intr_info_t *ii = xfer->hcpriv;
2450 uhci_softc_t *sc = ii->sc;
2451 struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
2452
2453 LIST_REMOVE(ii, list); /* remove from active list */
2454
2455 uhci_remove_bulk(sc, upipe->u.bulk.sqh);
2456
2457 uhci_free_std_chain(sc, ii->stdstart, 0);
2458
2459 DPRINTFN(5, ("uhci_bulk_done: length=%d\n", xfer->actlen));
2460 }
2461
2462 /* Add interrupt QH, called with vflock. */
2463 void
2464 uhci_add_intr(sc, n, sqh)
2465 uhci_softc_t *sc;
2466 int n;
2467 uhci_soft_qh_t *sqh;
2468 {
2469 struct uhci_vframe *vf = &sc->sc_vframes[n];
2470 uhci_soft_qh_t *eqh;
2471
2472 DPRINTFN(4, ("uhci_add_intr: n=%d sqh=%p\n", n, sqh));
2473 eqh = vf->eqh;
2474 sqh->hlink = eqh->hlink;
2475 sqh->qh.qh_hlink = eqh->qh.qh_hlink;
2476 eqh->hlink = sqh;
2477 eqh->qh.qh_hlink = htole32(sqh->physaddr | UHCI_PTR_Q);
2478 vf->eqh = sqh;
2479 vf->bandwidth++;
2480 }
2481
2482 /* Remove interrupt QH, called with vflock. */
2483 void
2484 uhci_remove_intr(sc, n, sqh)
2485 uhci_softc_t *sc;
2486 int n;
2487 uhci_soft_qh_t *sqh;
2488 {
2489 struct uhci_vframe *vf = &sc->sc_vframes[n];
2490 uhci_soft_qh_t *pqh;
2491
2492 DPRINTFN(4, ("uhci_remove_intr: n=%d sqh=%p\n", n, sqh));
2493
2494 for (pqh = vf->hqh; pqh->hlink != sqh; pqh = pqh->hlink)
2495 #if defined(DIAGNOSTIC) || defined(UHCI_DEBUG)
2496 if (le32toh(pqh->qh.qh_hlink) & UHCI_PTR_T) {
2497 DPRINTF(("uhci_remove_intr: QH not found\n"));
2498 return;
2499 }
2500 #else
2501 ;
2502 #endif
2503 pqh->hlink = sqh->hlink;
2504 pqh->qh.qh_hlink = sqh->qh.qh_hlink;
2505 if (vf->eqh == sqh)
2506 vf->eqh = pqh;
2507 vf->bandwidth--;
2508 }
2509
2510 usbd_status
2511 uhci_device_setintr(sc, upipe, ival)
2512 uhci_softc_t *sc;
2513 struct uhci_pipe *upipe;
2514 int ival;
2515 {
2516 uhci_soft_qh_t *sqh;
2517 int i, npoll, s;
2518 u_int bestbw, bw, bestoffs, offs;
2519
2520 DPRINTFN(2, ("uhci_setintr: pipe=%p\n", upipe));
2521 if (ival == 0) {
2522 printf("uhci_setintr: 0 interval\n");
2523 return (USBD_INVAL);
2524 }
2525
2526 if (ival > UHCI_VFRAMELIST_COUNT)
2527 ival = UHCI_VFRAMELIST_COUNT;
2528 npoll = (UHCI_VFRAMELIST_COUNT + ival - 1) / ival;
2529 DPRINTFN(2, ("uhci_setintr: ival=%d npoll=%d\n", ival, npoll));
2530
2531 upipe->u.intr.npoll = npoll;
2532 upipe->u.intr.qhs =
2533 malloc(npoll * sizeof(uhci_soft_qh_t *), M_USBHC, M_WAITOK);
2534
2535 /*
2536 * Figure out which offset in the schedule that has most
2537 * bandwidth left over.
2538 */
2539 #define MOD(i) ((i) & (UHCI_VFRAMELIST_COUNT-1))
2540 for (bestoffs = offs = 0, bestbw = ~0; offs < ival; offs++) {
2541 for (bw = i = 0; i < npoll; i++)
2542 bw += sc->sc_vframes[MOD(i * ival + offs)].bandwidth;
2543 if (bw < bestbw) {
2544 bestbw = bw;
2545 bestoffs = offs;
2546 }
2547 }
2548 DPRINTFN(1, ("uhci_setintr: bw=%d offs=%d\n", bestbw, bestoffs));
2549
2550 upipe->iinfo->stdstart = 0;
2551 for(i = 0; i < npoll; i++) {
2552 upipe->u.intr.qhs[i] = sqh = uhci_alloc_sqh(sc);
2553 sqh->elink = 0;
2554 sqh->qh.qh_elink = htole32(UHCI_PTR_T);
2555 sqh->pos = MOD(i * ival + bestoffs);
2556 sqh->intr_info = upipe->iinfo;
2557 }
2558 #undef MOD
2559
2560 s = splusb();
2561 LIST_INSERT_HEAD(&sc->sc_intrhead, upipe->iinfo, list);
2562 splx(s);
2563
2564 uhci_lock_frames(sc);
2565 /* Enter QHs into the controller data structures. */
2566 for(i = 0; i < npoll; i++)
2567 uhci_add_intr(sc, upipe->u.intr.qhs[i]->pos,
2568 upipe->u.intr.qhs[i]);
2569 uhci_unlock_frames(sc);
2570
2571 DPRINTFN(5, ("uhci_setintr: returns %p\n", upipe));
2572 return (USBD_NORMAL_COMPLETION);
2573 }
2574
2575 /* Open a new pipe. */
2576 usbd_status
2577 uhci_open(pipe)
2578 usbd_pipe_handle pipe;
2579 {
2580 uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus;
2581 struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
2582 usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc;
2583 usbd_status err;
2584 int ival;
2585
2586 DPRINTFN(1, ("uhci_open: pipe=%p, addr=%d, endpt=%d (%d)\n",
2587 pipe, pipe->device->address,
2588 ed->bEndpointAddress, sc->sc_addr));
2589 if (pipe->device->address == sc->sc_addr) {
2590 switch (ed->bEndpointAddress) {
2591 case USB_CONTROL_ENDPOINT:
2592 pipe->methods = &uhci_root_ctrl_methods;
2593 break;
2594 case UE_DIR_IN | UHCI_INTR_ENDPT:
2595 pipe->methods = &uhci_root_intr_methods;
2596 break;
2597 default:
2598 return (USBD_INVAL);
2599 }
2600 } else {
2601 upipe->iinfo = uhci_alloc_intr_info(sc);
2602 if (upipe->iinfo == 0)
2603 return (USBD_NOMEM);
2604 switch (ed->bmAttributes & UE_XFERTYPE) {
2605 case UE_CONTROL:
2606 pipe->methods = &uhci_device_ctrl_methods;
2607 upipe->u.ctl.sqh = uhci_alloc_sqh(sc);
2608 if (upipe->u.ctl.sqh == NULL)
2609 goto bad;
2610 upipe->u.ctl.setup = uhci_alloc_std(sc);
2611 if (upipe->u.ctl.setup == NULL) {
2612 uhci_free_sqh(sc, upipe->u.ctl.sqh);
2613 goto bad;
2614 }
2615 upipe->u.ctl.stat = uhci_alloc_std(sc);
2616 if (upipe->u.ctl.stat == NULL) {
2617 uhci_free_sqh(sc, upipe->u.ctl.sqh);
2618 uhci_free_std(sc, upipe->u.ctl.setup);
2619 goto bad;
2620 }
2621 err = usb_allocmem(&sc->sc_bus,
2622 sizeof(usb_device_request_t),
2623 0, &upipe->u.ctl.reqdma);
2624 if (err) {
2625 uhci_free_sqh(sc, upipe->u.ctl.sqh);
2626 uhci_free_std(sc, upipe->u.ctl.setup);
2627 uhci_free_std(sc, upipe->u.ctl.stat);
2628 goto bad;
2629 }
2630 break;
2631 case UE_INTERRUPT:
2632 pipe->methods = &uhci_device_intr_methods;
2633 ival = pipe->interval;
2634 if (ival == USBD_DEFAULT_INTERVAL)
2635 ival = ed->bInterval;
2636 return (uhci_device_setintr(sc, upipe, ival));
2637 case UE_ISOCHRONOUS:
2638 pipe->methods = &uhci_device_isoc_methods;
2639 return (uhci_setup_isoc(pipe));
2640 case UE_BULK:
2641 pipe->methods = &uhci_device_bulk_methods;
2642 upipe->u.bulk.sqh = uhci_alloc_sqh(sc);
2643 if (upipe->u.bulk.sqh == NULL)
2644 goto bad;
2645 break;
2646 }
2647 }
2648 return (USBD_NORMAL_COMPLETION);
2649
2650 bad:
2651 uhci_free_intr_info(upipe->iinfo);
2652 return (USBD_NOMEM);
2653 }
2654
2655 /*
2656 * Data structures and routines to emulate the root hub.
2657 */
2658 usb_device_descriptor_t uhci_devd = {
2659 USB_DEVICE_DESCRIPTOR_SIZE,
2660 UDESC_DEVICE, /* type */
2661 {0x00, 0x01}, /* USB version */
2662 UDCLASS_HUB, /* class */
2663 UDSUBCLASS_HUB, /* subclass */
2664 0, /* protocol */
2665 64, /* max packet */
2666 {0},{0},{0x00,0x01}, /* device id */
2667 1,2,0, /* string indicies */
2668 1 /* # of configurations */
2669 };
2670
2671 usb_config_descriptor_t uhci_confd = {
2672 USB_CONFIG_DESCRIPTOR_SIZE,
2673 UDESC_CONFIG,
2674 {USB_CONFIG_DESCRIPTOR_SIZE +
2675 USB_INTERFACE_DESCRIPTOR_SIZE +
2676 USB_ENDPOINT_DESCRIPTOR_SIZE},
2677 1,
2678 1,
2679 0,
2680 UC_SELF_POWERED,
2681 0 /* max power */
2682 };
2683
2684 usb_interface_descriptor_t uhci_ifcd = {
2685 USB_INTERFACE_DESCRIPTOR_SIZE,
2686 UDESC_INTERFACE,
2687 0,
2688 0,
2689 1,
2690 UICLASS_HUB,
2691 UISUBCLASS_HUB,
2692 0,
2693 0
2694 };
2695
2696 usb_endpoint_descriptor_t uhci_endpd = {
2697 USB_ENDPOINT_DESCRIPTOR_SIZE,
2698 UDESC_ENDPOINT,
2699 UE_DIR_IN | UHCI_INTR_ENDPT,
2700 UE_INTERRUPT,
2701 {8},
2702 255
2703 };
2704
2705 usb_hub_descriptor_t uhci_hubd_piix = {
2706 USB_HUB_DESCRIPTOR_SIZE,
2707 UDESC_HUB,
2708 2,
2709 { UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL, 0 },
2710 50, /* power on to power good */
2711 0,
2712 { 0x00 }, /* both ports are removable */
2713 };
2714
2715 int
2716 uhci_str(p, l, s)
2717 usb_string_descriptor_t *p;
2718 int l;
2719 char *s;
2720 {
2721 int i;
2722
2723 if (l == 0)
2724 return (0);
2725 p->bLength = 2 * strlen(s) + 2;
2726 if (l == 1)
2727 return (1);
2728 p->bDescriptorType = UDESC_STRING;
2729 l -= 2;
2730 for (i = 0; s[i] && l > 1; i++, l -= 2)
2731 USETW2(p->bString[i], 0, s[i]);
2732 return (2*i+2);
2733 }
2734
2735 /*
2736 * Simulate a hardware hub by handling all the necessary requests.
2737 */
2738 usbd_status
2739 uhci_root_ctrl_transfer(xfer)
2740 usbd_xfer_handle xfer;
2741 {
2742 usbd_status err;
2743
2744 /* Insert last in queue. */
2745 err = usb_insert_transfer(xfer);
2746 if (err)
2747 return (err);
2748
2749 /* Pipe isn't running (otherwise err would be USBD_INPROG),
2750 * start first
2751 */
2752 return (uhci_root_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
2753 }
2754
2755 usbd_status
2756 uhci_root_ctrl_start(xfer)
2757 usbd_xfer_handle xfer;
2758 {
2759 uhci_softc_t *sc = (uhci_softc_t *)xfer->pipe->device->bus;
2760 usb_device_request_t *req;
2761 void *buf = NULL;
2762 int port, x;
2763 int s, len, value, index, status, change, l, totlen = 0;
2764 usb_port_status_t ps;
2765 usbd_status err;
2766
2767 if (sc->sc_dying)
2768 return (USBD_IOERROR);
2769
2770 #ifdef DIAGNOSTIC
2771 if (!(xfer->rqflags & URQ_REQUEST))
2772 panic("uhci_root_ctrl_transfer: not a request\n");
2773 #endif
2774 req = &xfer->request;
2775
2776 DPRINTFN(2,("uhci_root_ctrl_control type=0x%02x request=%02x\n",
2777 req->bmRequestType, req->bRequest));
2778
2779 len = UGETW(req->wLength);
2780 value = UGETW(req->wValue);
2781 index = UGETW(req->wIndex);
2782
2783 if (len != 0)
2784 buf = KERNADDR(&xfer->dmabuf);
2785
2786 #define C(x,y) ((x) | ((y) << 8))
2787 switch(C(req->bRequest, req->bmRequestType)) {
2788 case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE):
2789 case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE):
2790 case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT):
2791 /*
2792 * DEVICE_REMOTE_WAKEUP and ENDPOINT_HALT are no-ops
2793 * for the integrated root hub.
2794 */
2795 break;
2796 case C(UR_GET_CONFIG, UT_READ_DEVICE):
2797 if (len > 0) {
2798 *(u_int8_t *)buf = sc->sc_conf;
2799 totlen = 1;
2800 }
2801 break;
2802 case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
2803 DPRINTFN(2,("uhci_root_ctrl_control wValue=0x%04x\n", value));
2804 switch(value >> 8) {
2805 case UDESC_DEVICE:
2806 if ((value & 0xff) != 0) {
2807 err = USBD_IOERROR;
2808 goto ret;
2809 }
2810 totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE);
2811 USETW(uhci_devd.idVendor, sc->sc_id_vendor);
2812 memcpy(buf, &uhci_devd, l);
2813 break;
2814 case UDESC_CONFIG:
2815 if ((value & 0xff) != 0) {
2816 err = USBD_IOERROR;
2817 goto ret;
2818 }
2819 totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE);
2820 memcpy(buf, &uhci_confd, l);
2821 buf = (char *)buf + l;
2822 len -= l;
2823 l = min(len, USB_INTERFACE_DESCRIPTOR_SIZE);
2824 totlen += l;
2825 memcpy(buf, &uhci_ifcd, l);
2826 buf = (char *)buf + l;
2827 len -= l;
2828 l = min(len, USB_ENDPOINT_DESCRIPTOR_SIZE);
2829 totlen += l;
2830 memcpy(buf, &uhci_endpd, l);
2831 break;
2832 case UDESC_STRING:
2833 if (len == 0)
2834 break;
2835 *(u_int8_t *)buf = 0;
2836 totlen = 1;
2837 switch (value & 0xff) {
2838 case 1: /* Vendor */
2839 totlen = uhci_str(buf, len, sc->sc_vendor);
2840 break;
2841 case 2: /* Product */
2842 totlen = uhci_str(buf, len, "UHCI root hub");
2843 break;
2844 }
2845 break;
2846 default:
2847 err = USBD_IOERROR;
2848 goto ret;
2849 }
2850 break;
2851 case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
2852 if (len > 0) {
2853 *(u_int8_t *)buf = 0;
2854 totlen = 1;
2855 }
2856 break;
2857 case C(UR_GET_STATUS, UT_READ_DEVICE):
2858 if (len > 1) {
2859 USETW(((usb_status_t *)buf)->wStatus,UDS_SELF_POWERED);
2860 totlen = 2;
2861 }
2862 break;
2863 case C(UR_GET_STATUS, UT_READ_INTERFACE):
2864 case C(UR_GET_STATUS, UT_READ_ENDPOINT):
2865 if (len > 1) {
2866 USETW(((usb_status_t *)buf)->wStatus, 0);
2867 totlen = 2;
2868 }
2869 break;
2870 case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
2871 if (value >= USB_MAX_DEVICES) {
2872 err = USBD_IOERROR;
2873 goto ret;
2874 }
2875 sc->sc_addr = value;
2876 break;
2877 case C(UR_SET_CONFIG, UT_WRITE_DEVICE):
2878 if (value != 0 && value != 1) {
2879 err = USBD_IOERROR;
2880 goto ret;
2881 }
2882 sc->sc_conf = value;
2883 break;
2884 case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE):
2885 break;
2886 case C(UR_SET_FEATURE, UT_WRITE_DEVICE):
2887 case C(UR_SET_FEATURE, UT_WRITE_INTERFACE):
2888 case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
2889 err = USBD_IOERROR;
2890 goto ret;
2891 case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
2892 break;
2893 case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT):
2894 break;
2895 /* Hub requests */
2896 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE):
2897 break;
2898 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER):
2899 DPRINTFN(3, ("uhci_root_ctrl_control: UR_CLEAR_PORT_FEATURE "
2900 "port=%d feature=%d\n",
2901 index, value));
2902 if (index == 1)
2903 port = UHCI_PORTSC1;
2904 else if (index == 2)
2905 port = UHCI_PORTSC2;
2906 else {
2907 err = USBD_IOERROR;
2908 goto ret;
2909 }
2910 switch(value) {
2911 case UHF_PORT_ENABLE:
2912 x = UREAD2(sc, port);
2913 UWRITE2(sc, port, x & ~UHCI_PORTSC_PE);
2914 break;
2915 case UHF_PORT_SUSPEND:
2916 x = UREAD2(sc, port);
2917 UWRITE2(sc, port, x & ~UHCI_PORTSC_SUSP);
2918 break;
2919 case UHF_PORT_RESET:
2920 x = UREAD2(sc, port);
2921 UWRITE2(sc, port, x & ~UHCI_PORTSC_PR);
2922 break;
2923 case UHF_C_PORT_CONNECTION:
2924 x = UREAD2(sc, port);
2925 UWRITE2(sc, port, x | UHCI_PORTSC_CSC);
2926 break;
2927 case UHF_C_PORT_ENABLE:
2928 x = UREAD2(sc, port);
2929 UWRITE2(sc, port, x | UHCI_PORTSC_POEDC);
2930 break;
2931 case UHF_C_PORT_OVER_CURRENT:
2932 x = UREAD2(sc, port);
2933 UWRITE2(sc, port, x | UHCI_PORTSC_OCIC);
2934 break;
2935 case UHF_C_PORT_RESET:
2936 sc->sc_isreset = 0;
2937 err = USBD_NORMAL_COMPLETION;
2938 goto ret;
2939 case UHF_PORT_CONNECTION:
2940 case UHF_PORT_OVER_CURRENT:
2941 case UHF_PORT_POWER:
2942 case UHF_PORT_LOW_SPEED:
2943 case UHF_C_PORT_SUSPEND:
2944 default:
2945 err = USBD_IOERROR;
2946 goto ret;
2947 }
2948 break;
2949 case C(UR_GET_BUS_STATE, UT_READ_CLASS_OTHER):
2950 if (index == 1)
2951 port = UHCI_PORTSC1;
2952 else if (index == 2)
2953 port = UHCI_PORTSC2;
2954 else {
2955 err = USBD_IOERROR;
2956 goto ret;
2957 }
2958 if (len > 0) {
2959 *(u_int8_t *)buf =
2960 (UREAD2(sc, port) & UHCI_PORTSC_LS) >>
2961 UHCI_PORTSC_LS_SHIFT;
2962 totlen = 1;
2963 }
2964 break;
2965 case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
2966 if (value != 0) {
2967 err = USBD_IOERROR;
2968 goto ret;
2969 }
2970 l = min(len, USB_HUB_DESCRIPTOR_SIZE);
2971 totlen = l;
2972 memcpy(buf, &uhci_hubd_piix, l);
2973 break;
2974 case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
2975 if (len != 4) {
2976 err = USBD_IOERROR;
2977 goto ret;
2978 }
2979 memset(buf, 0, len);
2980 totlen = len;
2981 break;
2982 case C(UR_GET_STATUS, UT_READ_CLASS_OTHER):
2983 if (index == 1)
2984 port = UHCI_PORTSC1;
2985 else if (index == 2)
2986 port = UHCI_PORTSC2;
2987 else {
2988 err = USBD_IOERROR;
2989 goto ret;
2990 }
2991 if (len != 4) {
2992 err = USBD_IOERROR;
2993 goto ret;
2994 }
2995 x = UREAD2(sc, port);
2996 status = change = 0;
2997 if (x & UHCI_PORTSC_CCS )
2998 status |= UPS_CURRENT_CONNECT_STATUS;
2999 if (x & UHCI_PORTSC_CSC )
3000 change |= UPS_C_CONNECT_STATUS;
3001 if (x & UHCI_PORTSC_PE )
3002 status |= UPS_PORT_ENABLED;
3003 if (x & UHCI_PORTSC_POEDC)
3004 change |= UPS_C_PORT_ENABLED;
3005 if (x & UHCI_PORTSC_OCI )
3006 status |= UPS_OVERCURRENT_INDICATOR;
3007 if (x & UHCI_PORTSC_OCIC )
3008 change |= UPS_C_OVERCURRENT_INDICATOR;
3009 if (x & UHCI_PORTSC_SUSP )
3010 status |= UPS_SUSPEND;
3011 if (x & UHCI_PORTSC_LSDA )
3012 status |= UPS_LOW_SPEED;
3013 status |= UPS_PORT_POWER;
3014 if (sc->sc_isreset)
3015 change |= UPS_C_PORT_RESET;
3016 USETW(ps.wPortStatus, status);
3017 USETW(ps.wPortChange, change);
3018 l = min(len, sizeof ps);
3019 memcpy(buf, &ps, l);
3020 totlen = l;
3021 break;
3022 case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
3023 err = USBD_IOERROR;
3024 goto ret;
3025 case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE):
3026 break;
3027 case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER):
3028 if (index == 1)
3029 port = UHCI_PORTSC1;
3030 else if (index == 2)
3031 port = UHCI_PORTSC2;
3032 else {
3033 err = USBD_IOERROR;
3034 goto ret;
3035 }
3036 switch(value) {
3037 case UHF_PORT_ENABLE:
3038 x = UREAD2(sc, port);
3039 UWRITE2(sc, port, x | UHCI_PORTSC_PE);
3040 break;
3041 case UHF_PORT_SUSPEND:
3042 x = UREAD2(sc, port);
3043 UWRITE2(sc, port, x | UHCI_PORTSC_SUSP);
3044 break;
3045 case UHF_PORT_RESET:
3046 x = UREAD2(sc, port);
3047 UWRITE2(sc, port, x | UHCI_PORTSC_PR);
3048 usb_delay_ms(&sc->sc_bus, 10);
3049 UWRITE2(sc, port, x & ~UHCI_PORTSC_PR);
3050 delay(100);
3051 x = UREAD2(sc, port);
3052 UWRITE2(sc, port, x | UHCI_PORTSC_PE);
3053 delay(100);
3054 DPRINTFN(3,("uhci port %d reset, status = 0x%04x\n",
3055 index, UREAD2(sc, port)));
3056 sc->sc_isreset = 1;
3057 break;
3058 case UHF_C_PORT_CONNECTION:
3059 case UHF_C_PORT_ENABLE:
3060 case UHF_C_PORT_OVER_CURRENT:
3061 case UHF_PORT_CONNECTION:
3062 case UHF_PORT_OVER_CURRENT:
3063 case UHF_PORT_POWER:
3064 case UHF_PORT_LOW_SPEED:
3065 case UHF_C_PORT_SUSPEND:
3066 case UHF_C_PORT_RESET:
3067 default:
3068 err = USBD_IOERROR;
3069 goto ret;
3070 }
3071 break;
3072 default:
3073 err = USBD_IOERROR;
3074 goto ret;
3075 }
3076 xfer->actlen = totlen;
3077 err = USBD_NORMAL_COMPLETION;
3078 ret:
3079 xfer->status = err;
3080 xfer->hcpriv = 0;
3081 s = splusb();
3082 usb_transfer_complete(xfer);
3083 splx(s);
3084 return (USBD_IN_PROGRESS);
3085 }
3086
3087 /* Abort a root control request. */
3088 void
3089 uhci_root_ctrl_abort(xfer)
3090 usbd_xfer_handle xfer;
3091 {
3092 /* Nothing to do, all transfers are synchronous. */
3093 }
3094
3095 /* Close the root pipe. */
3096 void
3097 uhci_root_ctrl_close(pipe)
3098 usbd_pipe_handle pipe;
3099 {
3100 DPRINTF(("uhci_root_ctrl_close\n"));
3101 }
3102
3103 /* Abort a root interrupt request. */
3104 void
3105 uhci_root_intr_abort(xfer)
3106 usbd_xfer_handle xfer;
3107 {
3108 uhci_softc_t *sc = (uhci_softc_t *)xfer->pipe->device->bus;
3109
3110 usb_untimeout(uhci_timo, xfer, xfer->timo_handle);
3111 sc->sc_has_timo = NULL;
3112
3113 if (xfer->pipe->intrxfer == xfer) {
3114 DPRINTF(("uhci_root_intr_abort: remove\n"));
3115 xfer->pipe->intrxfer = 0;
3116 }
3117 xfer->status = USBD_CANCELLED;
3118 usb_transfer_complete(xfer);
3119 }
3120
3121 usbd_status
3122 uhci_root_intr_transfer(xfer)
3123 usbd_xfer_handle xfer;
3124 {
3125 usbd_status err;
3126
3127 /* Insert last in queue. */
3128 err = usb_insert_transfer(xfer);
3129 if (err)
3130 return (err);
3131
3132 /* Pipe isn't running (otherwise err would be USBD_INPROG),
3133 * start first
3134 */
3135 return (uhci_root_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
3136 }
3137
3138 /* Start a transfer on the root interrupt pipe */
3139 usbd_status
3140 uhci_root_intr_start(xfer)
3141 usbd_xfer_handle xfer;
3142 {
3143 usbd_pipe_handle pipe = xfer->pipe;
3144 uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus;
3145
3146 DPRINTFN(3, ("uhci_root_intr_transfer: xfer=%p len=%d flags=%d\n",
3147 xfer, xfer->length, xfer->flags));
3148
3149 if (sc->sc_dying)
3150 return (USBD_IOERROR);
3151
3152 sc->sc_ival = MS_TO_TICKS(xfer->pipe->endpoint->edesc->bInterval);
3153 usb_timeout(uhci_timo, xfer, sc->sc_ival, xfer->timo_handle);
3154 sc->sc_has_timo = xfer;
3155 return (USBD_IN_PROGRESS);
3156 }
3157
3158 /* Close the root interrupt pipe. */
3159 void
3160 uhci_root_intr_close(pipe)
3161 usbd_pipe_handle pipe;
3162 {
3163 uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus;
3164
3165 usb_untimeout(uhci_timo, pipe->intrxfer, pipe->intrxfer->timo_handle);
3166 sc->sc_has_timo = NULL;
3167 DPRINTF(("uhci_root_intr_close\n"));
3168 }
3169