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