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