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