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