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