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