1 /* $NetBSD: uhci.c,v 1.230 2009/11/12 19:53:56 dyoung Exp $ */
2 /* $FreeBSD: src/sys/dev/usb/uhci.c,v 1.33 1999/11/17 22:33:41 n_hibma Exp $ */
5 * Copyright (c) 1998, 2004 The NetBSD Foundation, Inc.
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Lennart Augustsson (lennart@augustsson.net) at
10 * Carlstedt Research & Technology.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
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.
21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
35 * USB Universal Host Controller driver.
36 * Handles e.g. PIIX3 and PIIX4.
38 * UHCI spec: http://www.intel.com/technology/usb/spec.htm
39 * USB spec: http://www.usb.org/developers/docs/
40 * PIIXn spec: ftp://download.intel.com/design/intarch/datashts/29055002.pdf
41 * ftp://download.intel.com/design/intarch/datashts/29056201.pdf
44 #include <sys/cdefs.h>
45 __KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.230 2009/11/12 19:53:56 dyoung Exp $");
47 #include <sys/param.h>
48 #include <sys/systm.h>
49 #include <sys/kernel.h>
50 #include <sys/malloc.h>
51 #include <sys/device.h>
52 #include <sys/select.h>
53 #include <sys/extent.h>
54 #include <uvm/uvm_extern.h>
56 #include <sys/queue.h>
59 #include <machine/endian.h>
61 #include <dev/usb/usb.h>
62 #include <dev/usb/usbdi.h>
63 #include <dev/usb/usbdivar.h>
64 #include <dev/usb/usb_mem.h>
65 #include <dev/usb/usb_quirks.h>
67 #include <dev/usb/uhcireg.h>
68 #include <dev/usb/uhcivar.h>
69 #include <dev/usb/usbroothub_subr.h>
71 /* Use bandwidth reclamation for control transfers. Some devices choke on it. */
72 /*#define UHCI_CTL_LOOP */
78 #define DPRINTF(x) if (uhcidebug) printf x
79 #define DPRINTFN(n,x) if (uhcidebug>(n)) printf x
88 * The UHCI controller is little endian, so on big endian machines
89 * the data stored in memory needs to be swapped.
93 struct usbd_pipe pipe
;
97 usbd_xfer_handle abortstart
, abortend
;
99 /* Info needed for different pipe kinds. */
105 uhci_soft_td_t
*setup
, *stat
;
112 uhci_soft_qh_t
**qhs
;
122 uhci_soft_td_t
**stds
;
128 Static
void uhci_globalreset(uhci_softc_t
*);
129 Static usbd_status
uhci_portreset(uhci_softc_t
*, int);
130 Static
void uhci_reset(uhci_softc_t
*);
131 Static usbd_status
uhci_run(uhci_softc_t
*, int run
);
132 Static uhci_soft_td_t
*uhci_alloc_std(uhci_softc_t
*);
133 Static
void uhci_free_std(uhci_softc_t
*, uhci_soft_td_t
*);
134 Static uhci_soft_qh_t
*uhci_alloc_sqh(uhci_softc_t
*);
135 Static
void uhci_free_sqh(uhci_softc_t
*, uhci_soft_qh_t
*);
137 Static
void uhci_enter_ctl_q(uhci_softc_t
*, uhci_soft_qh_t
*,
139 Static
void uhci_exit_ctl_q(uhci_softc_t
*, uhci_soft_qh_t
*);
142 Static
void uhci_free_std_chain(uhci_softc_t
*,
143 uhci_soft_td_t
*, uhci_soft_td_t
*);
144 Static usbd_status
uhci_alloc_std_chain(struct uhci_pipe
*,
145 uhci_softc_t
*, int, int, u_int16_t
, usb_dma_t
*,
146 uhci_soft_td_t
**, uhci_soft_td_t
**);
147 Static
void uhci_poll_hub(void *);
148 Static
void uhci_waitintr(uhci_softc_t
*, usbd_xfer_handle
);
149 Static
void uhci_check_intr(uhci_softc_t
*, uhci_intr_info_t
*);
150 Static
void uhci_idone(uhci_intr_info_t
*);
152 Static
void uhci_abort_xfer(usbd_xfer_handle
, usbd_status status
);
154 Static
void uhci_timeout(void *);
155 Static
void uhci_timeout_task(void *);
156 Static
void uhci_add_ls_ctrl(uhci_softc_t
*, uhci_soft_qh_t
*);
157 Static
void uhci_add_hs_ctrl(uhci_softc_t
*, uhci_soft_qh_t
*);
158 Static
void uhci_add_bulk(uhci_softc_t
*, uhci_soft_qh_t
*);
159 Static
void uhci_remove_ls_ctrl(uhci_softc_t
*,uhci_soft_qh_t
*);
160 Static
void uhci_remove_hs_ctrl(uhci_softc_t
*,uhci_soft_qh_t
*);
161 Static
void uhci_remove_bulk(uhci_softc_t
*,uhci_soft_qh_t
*);
162 Static
void uhci_add_loop(uhci_softc_t
*sc
);
163 Static
void uhci_rem_loop(uhci_softc_t
*sc
);
165 Static usbd_status
uhci_setup_isoc(usbd_pipe_handle pipe
);
166 Static
void uhci_device_isoc_enter(usbd_xfer_handle
);
168 Static usbd_status
uhci_allocm(struct usbd_bus
*, usb_dma_t
*, u_int32_t
);
169 Static
void uhci_freem(struct usbd_bus
*, usb_dma_t
*);
171 Static usbd_xfer_handle
uhci_allocx(struct usbd_bus
*);
172 Static
void uhci_freex(struct usbd_bus
*, usbd_xfer_handle
);
174 Static usbd_status
uhci_device_ctrl_transfer(usbd_xfer_handle
);
175 Static usbd_status
uhci_device_ctrl_start(usbd_xfer_handle
);
176 Static
void uhci_device_ctrl_abort(usbd_xfer_handle
);
177 Static
void uhci_device_ctrl_close(usbd_pipe_handle
);
178 Static
void uhci_device_ctrl_done(usbd_xfer_handle
);
180 Static usbd_status
uhci_device_intr_transfer(usbd_xfer_handle
);
181 Static usbd_status
uhci_device_intr_start(usbd_xfer_handle
);
182 Static
void uhci_device_intr_abort(usbd_xfer_handle
);
183 Static
void uhci_device_intr_close(usbd_pipe_handle
);
184 Static
void uhci_device_intr_done(usbd_xfer_handle
);
186 Static usbd_status
uhci_device_bulk_transfer(usbd_xfer_handle
);
187 Static usbd_status
uhci_device_bulk_start(usbd_xfer_handle
);
188 Static
void uhci_device_bulk_abort(usbd_xfer_handle
);
189 Static
void uhci_device_bulk_close(usbd_pipe_handle
);
190 Static
void uhci_device_bulk_done(usbd_xfer_handle
);
192 Static usbd_status
uhci_device_isoc_transfer(usbd_xfer_handle
);
193 Static usbd_status
uhci_device_isoc_start(usbd_xfer_handle
);
194 Static
void uhci_device_isoc_abort(usbd_xfer_handle
);
195 Static
void uhci_device_isoc_close(usbd_pipe_handle
);
196 Static
void uhci_device_isoc_done(usbd_xfer_handle
);
198 Static usbd_status
uhci_root_ctrl_transfer(usbd_xfer_handle
);
199 Static usbd_status
uhci_root_ctrl_start(usbd_xfer_handle
);
200 Static
void uhci_root_ctrl_abort(usbd_xfer_handle
);
201 Static
void uhci_root_ctrl_close(usbd_pipe_handle
);
202 Static
void uhci_root_ctrl_done(usbd_xfer_handle
);
204 Static usbd_status
uhci_root_intr_transfer(usbd_xfer_handle
);
205 Static usbd_status
uhci_root_intr_start(usbd_xfer_handle
);
206 Static
void uhci_root_intr_abort(usbd_xfer_handle
);
207 Static
void uhci_root_intr_close(usbd_pipe_handle
);
208 Static
void uhci_root_intr_done(usbd_xfer_handle
);
210 Static usbd_status
uhci_open(usbd_pipe_handle
);
211 Static
void uhci_poll(struct usbd_bus
*);
212 Static
void uhci_softintr(void *);
214 Static usbd_status
uhci_device_request(usbd_xfer_handle xfer
);
216 Static
void uhci_add_intr(uhci_softc_t
*, uhci_soft_qh_t
*);
217 Static
void uhci_remove_intr(uhci_softc_t
*, uhci_soft_qh_t
*);
218 Static usbd_status
uhci_device_setintr(uhci_softc_t
*sc
,
219 struct uhci_pipe
*pipe
, int ival
);
221 Static
void uhci_device_clear_toggle(usbd_pipe_handle pipe
);
222 Static
void uhci_noop(usbd_pipe_handle pipe
);
224 Static
inline uhci_soft_qh_t
*uhci_find_prev_qh(uhci_soft_qh_t
*,
228 Static
void uhci_dump_all(uhci_softc_t
*);
229 Static
void uhci_dumpregs(uhci_softc_t
*);
230 Static
void uhci_dump_qhs(uhci_soft_qh_t
*);
231 Static
void uhci_dump_qh(uhci_soft_qh_t
*);
232 Static
void uhci_dump_tds(uhci_soft_td_t
*);
233 Static
void uhci_dump_td(uhci_soft_td_t
*);
234 Static
void uhci_dump_ii(uhci_intr_info_t
*ii
);
235 void uhci_dump(void);
238 #define UBARR(sc) bus_space_barrier((sc)->iot, (sc)->ioh, 0, (sc)->sc_size, \
239 BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE)
240 #define UWRITE1(sc, r, x) \
241 do { UBARR(sc); bus_space_write_1((sc)->iot, (sc)->ioh, (r), (x)); \
242 } while (/*CONSTCOND*/0)
243 #define UWRITE2(sc, r, x) \
244 do { UBARR(sc); bus_space_write_2((sc)->iot, (sc)->ioh, (r), (x)); \
245 } while (/*CONSTCOND*/0)
246 #define UWRITE4(sc, r, x) \
247 do { UBARR(sc); bus_space_write_4((sc)->iot, (sc)->ioh, (r), (x)); \
248 } while (/*CONSTCOND*/0)
249 static __inline
uint8_t
250 UREAD1(uhci_softc_t
*sc
, bus_size_t r
)
254 return bus_space_read_1(sc
->iot
, sc
->ioh
, r
);
257 static __inline
uint16_t
258 UREAD2(uhci_softc_t
*sc
, bus_size_t r
)
262 return bus_space_read_2(sc
->iot
, sc
->ioh
, r
);
265 static __inline
uint32_t
266 UREAD4(uhci_softc_t
*sc
, bus_size_t r
)
270 return bus_space_read_4(sc
->iot
, sc
->ioh
, r
);
273 #define UHCICMD(sc, cmd) UWRITE2(sc, UHCI_CMD, cmd)
274 #define UHCISTS(sc) UREAD2(sc, UHCI_STS)
276 #define UHCI_RESET_TIMEOUT 100 /* ms, reset timeout */
278 #define UHCI_CURFRAME(sc) (UREAD2(sc, UHCI_FRNUM) & UHCI_FRNUM_MASK)
280 #define UHCI_INTR_ENDPT 1
282 const struct usbd_bus_methods uhci_bus_methods
= {
292 const struct usbd_pipe_methods uhci_root_ctrl_methods
= {
293 uhci_root_ctrl_transfer
,
294 uhci_root_ctrl_start
,
295 uhci_root_ctrl_abort
,
296 uhci_root_ctrl_close
,
301 const struct usbd_pipe_methods uhci_root_intr_methods
= {
302 uhci_root_intr_transfer
,
303 uhci_root_intr_start
,
304 uhci_root_intr_abort
,
305 uhci_root_intr_close
,
310 const struct usbd_pipe_methods uhci_device_ctrl_methods
= {
311 uhci_device_ctrl_transfer
,
312 uhci_device_ctrl_start
,
313 uhci_device_ctrl_abort
,
314 uhci_device_ctrl_close
,
316 uhci_device_ctrl_done
,
319 const struct usbd_pipe_methods uhci_device_intr_methods
= {
320 uhci_device_intr_transfer
,
321 uhci_device_intr_start
,
322 uhci_device_intr_abort
,
323 uhci_device_intr_close
,
324 uhci_device_clear_toggle
,
325 uhci_device_intr_done
,
328 const struct usbd_pipe_methods uhci_device_bulk_methods
= {
329 uhci_device_bulk_transfer
,
330 uhci_device_bulk_start
,
331 uhci_device_bulk_abort
,
332 uhci_device_bulk_close
,
333 uhci_device_clear_toggle
,
334 uhci_device_bulk_done
,
337 const struct usbd_pipe_methods uhci_device_isoc_methods
= {
338 uhci_device_isoc_transfer
,
339 uhci_device_isoc_start
,
340 uhci_device_isoc_abort
,
341 uhci_device_isoc_close
,
343 uhci_device_isoc_done
,
346 #define uhci_add_intr_info(sc, ii) \
347 LIST_INSERT_HEAD(&(sc)->sc_intrhead, (ii), list)
348 #define uhci_del_intr_info(ii) \
350 LIST_REMOVE((ii), list); \
351 (ii)->list.le_prev = NULL; \
353 #define uhci_active_intr_info(ii) ((ii)->list.le_prev != NULL)
355 Static
inline uhci_soft_qh_t
*
356 uhci_find_prev_qh(uhci_soft_qh_t
*pqh
, uhci_soft_qh_t
*sqh
)
358 DPRINTFN(15,("uhci_find_prev_qh: pqh=%p sqh=%p\n", pqh
, sqh
));
360 for (; pqh
->hlink
!= sqh
; pqh
= pqh
->hlink
) {
361 #if defined(DIAGNOSTIC) || defined(UHCI_DEBUG)
362 usb_syncmem(&pqh
->dma
,
363 pqh
->offs
+ offsetof(uhci_qh_t
, qh_hlink
),
364 sizeof(pqh
->qh
.qh_hlink
),
365 BUS_DMASYNC_POSTWRITE
);
366 if (le32toh(pqh
->qh
.qh_hlink
) & UHCI_PTR_T
) {
367 printf("uhci_find_prev_qh: QH not found\n");
376 uhci_globalreset(uhci_softc_t
*sc
)
378 UHCICMD(sc
, UHCI_CMD_GRESET
); /* global reset */
379 usb_delay_ms(&sc
->sc_bus
, USB_BUS_RESET_DELAY
); /* wait a little */
380 UHCICMD(sc
, 0); /* do nothing */
384 uhci_init(uhci_softc_t
*sc
)
388 uhci_soft_qh_t
*clsqh
, *chsqh
, *bsqh
, *sqh
, *lsqh
;
391 DPRINTFN(1,("uhci_init: start\n"));
400 sc
->sc_suspend
= PWR_RESUME
;
402 UWRITE2(sc
, UHCI_INTR
, 0); /* disable interrupts */
403 uhci_globalreset(sc
); /* reset the controller */
406 usb_setup_reserve(sc
->sc_dev
, &sc
->sc_dma_reserve
, sc
->sc_bus
.dmatag
,
409 /* Allocate and initialize real frame array. */
410 err
= usb_allocmem(&sc
->sc_bus
,
411 UHCI_FRAMELIST_COUNT
* sizeof(uhci_physaddr_t
),
412 UHCI_FRAMELIST_ALIGN
, &sc
->sc_dma
);
415 sc
->sc_pframes
= KERNADDR(&sc
->sc_dma
, 0);
416 UWRITE2(sc
, UHCI_FRNUM
, 0); /* set frame number to 0 */
417 UWRITE4(sc
, UHCI_FLBASEADDR
, DMAADDR(&sc
->sc_dma
, 0)); /* set frame list*/
420 * Allocate a TD, inactive, that hangs from the last QH.
421 * This is to avoid a bug in the PIIX that makes it run berserk
424 std
= uhci_alloc_std(sc
);
427 std
->link
.std
= NULL
;
428 std
->td
.td_link
= htole32(UHCI_PTR_T
);
429 std
->td
.td_status
= htole32(0); /* inactive */
430 std
->td
.td_token
= htole32(0);
431 std
->td
.td_buffer
= htole32(0);
432 usb_syncmem(&std
->dma
, std
->offs
, sizeof(std
->td
),
433 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
435 /* Allocate the dummy QH marking the end and used for looping the QHs.*/
436 lsqh
= uhci_alloc_sqh(sc
);
440 lsqh
->qh
.qh_hlink
= htole32(UHCI_PTR_T
); /* end of QH chain */
442 lsqh
->qh
.qh_elink
= htole32(std
->physaddr
| UHCI_PTR_TD
);
443 sc
->sc_last_qh
= lsqh
;
444 usb_syncmem(&lsqh
->dma
, lsqh
->offs
, sizeof(lsqh
->qh
),
445 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
447 /* Allocate the dummy QH where bulk traffic will be queued. */
448 bsqh
= uhci_alloc_sqh(sc
);
452 bsqh
->qh
.qh_hlink
= htole32(lsqh
->physaddr
| UHCI_PTR_QH
);
454 bsqh
->qh
.qh_elink
= htole32(UHCI_PTR_T
);
455 sc
->sc_bulk_start
= sc
->sc_bulk_end
= bsqh
;
456 usb_syncmem(&bsqh
->dma
, bsqh
->offs
, sizeof(bsqh
->qh
),
457 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
459 /* Allocate dummy QH where high speed control traffic will be queued. */
460 chsqh
= uhci_alloc_sqh(sc
);
464 chsqh
->qh
.qh_hlink
= htole32(bsqh
->physaddr
| UHCI_PTR_QH
);
466 chsqh
->qh
.qh_elink
= htole32(UHCI_PTR_T
);
467 sc
->sc_hctl_start
= sc
->sc_hctl_end
= chsqh
;
468 usb_syncmem(&chsqh
->dma
, chsqh
->offs
, sizeof(chsqh
->qh
),
469 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
471 /* Allocate dummy QH where control traffic will be queued. */
472 clsqh
= uhci_alloc_sqh(sc
);
475 clsqh
->hlink
= chsqh
;
476 clsqh
->qh
.qh_hlink
= htole32(chsqh
->physaddr
| UHCI_PTR_QH
);
478 clsqh
->qh
.qh_elink
= htole32(UHCI_PTR_T
);
479 sc
->sc_lctl_start
= sc
->sc_lctl_end
= clsqh
;
480 usb_syncmem(&clsqh
->dma
, clsqh
->offs
, sizeof(clsqh
->qh
),
481 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
484 * Make all (virtual) frame list pointers point to the interrupt
485 * queue heads and the interrupt queue heads at the control
486 * queue head and point the physical frame list to the virtual.
488 for(i
= 0; i
< UHCI_VFRAMELIST_COUNT
; i
++) {
489 std
= uhci_alloc_std(sc
);
490 sqh
= uhci_alloc_sqh(sc
);
491 if (std
== NULL
|| sqh
== NULL
)
494 std
->td
.td_link
= htole32(sqh
->physaddr
| UHCI_PTR_QH
);
495 std
->td
.td_status
= htole32(UHCI_TD_IOS
); /* iso, inactive */
496 std
->td
.td_token
= htole32(0);
497 std
->td
.td_buffer
= htole32(0);
498 usb_syncmem(&std
->dma
, std
->offs
, sizeof(std
->td
),
499 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
501 sqh
->qh
.qh_hlink
= htole32(clsqh
->physaddr
| UHCI_PTR_QH
);
503 sqh
->qh
.qh_elink
= htole32(UHCI_PTR_T
);
504 usb_syncmem(&sqh
->dma
, sqh
->offs
, sizeof(sqh
->qh
),
505 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
506 sc
->sc_vframes
[i
].htd
= std
;
507 sc
->sc_vframes
[i
].etd
= std
;
508 sc
->sc_vframes
[i
].hqh
= sqh
;
509 sc
->sc_vframes
[i
].eqh
= sqh
;
511 j
< UHCI_FRAMELIST_COUNT
;
512 j
+= UHCI_VFRAMELIST_COUNT
)
513 sc
->sc_pframes
[j
] = htole32(std
->physaddr
);
515 usb_syncmem(&sc
->sc_dma
, 0,
516 UHCI_FRAMELIST_COUNT
* sizeof(uhci_physaddr_t
),
517 BUS_DMASYNC_PREWRITE
);
520 LIST_INIT(&sc
->sc_intrhead
);
522 SIMPLEQ_INIT(&sc
->sc_free_xfers
);
524 usb_callout_init(sc
->sc_poll_handle
);
526 /* Set up the bus struct. */
527 sc
->sc_bus
.methods
= &uhci_bus_methods
;
528 sc
->sc_bus
.pipe_size
= sizeof(struct uhci_pipe
);
530 UHCICMD(sc
, UHCI_CMD_MAXP
); /* Assume 64 byte packets at frame end */
532 DPRINTFN(1,("uhci_init: enabling\n"));
534 err
= uhci_run(sc
, 1); /* and here we go... */
535 UWRITE2(sc
, UHCI_INTR
, UHCI_INTR_TOCRCIE
| UHCI_INTR_RIE
|
536 UHCI_INTR_IOCE
| UHCI_INTR_SPIE
); /* enable interrupts */
541 uhci_activate(device_t self
, enum devact act
)
543 struct uhci_softc
*sc
= device_private(self
);
546 case DVACT_DEACTIVATE
:
555 uhci_childdet(device_t self
, device_t child
)
557 struct uhci_softc
*sc
= device_private(self
);
559 KASSERT(sc
->sc_child
== child
);
564 uhci_detach(struct uhci_softc
*sc
, int flags
)
566 usbd_xfer_handle xfer
;
569 if (sc
->sc_child
!= NULL
)
570 rv
= config_detach(sc
->sc_child
, flags
);
575 /* Free all xfers associated with this HC. */
577 xfer
= SIMPLEQ_FIRST(&sc
->sc_free_xfers
);
580 SIMPLEQ_REMOVE_HEAD(&sc
->sc_free_xfers
, next
);
584 callout_halt(&sc
->sc_poll_handle
, NULL
);
585 callout_destroy(&sc
->sc_poll_handle
);
587 /* XXX free other data structures XXX */
593 uhci_allocm(struct usbd_bus
*bus
, usb_dma_t
*dma
, u_int32_t size
)
595 struct uhci_softc
*sc
= bus
->hci_private
;
601 * Since we are allocating a buffer we can assume that we will
602 * need TDs for it. Since we don't want to allocate those from
603 * an interrupt context, we allocate them here and free them again.
604 * This is no guarantee that we'll get the TDs next time...
609 uhci_soft_td_t
**stds
;
610 DPRINTF(("uhci_allocm: get %d TDs\n", n
));
611 stds
= malloc(sizeof(uhci_soft_td_t
*) * n
, M_TEMP
,
614 stds
[i
] = uhci_alloc_std(sc
);
617 uhci_free_std(sc
, stds
[i
]);
622 status
= usb_allocmem(&sc
->sc_bus
, size
, 0, dma
);
623 if (status
== USBD_NOMEM
)
624 status
= usb_reserve_allocm(&sc
->sc_dma_reserve
, dma
, size
);
629 uhci_freem(struct usbd_bus
*bus
, usb_dma_t
*dma
)
631 if (dma
->block
->flags
& USB_DMA_RESERVE
) {
632 usb_reserve_freem(&((struct uhci_softc
*)bus
)->sc_dma_reserve
,
636 usb_freemem(&((struct uhci_softc
*)bus
)->sc_bus
, dma
);
640 uhci_allocx(struct usbd_bus
*bus
)
642 struct uhci_softc
*sc
= bus
->hci_private
;
643 usbd_xfer_handle xfer
;
645 xfer
= SIMPLEQ_FIRST(&sc
->sc_free_xfers
);
647 SIMPLEQ_REMOVE_HEAD(&sc
->sc_free_xfers
, next
);
649 if (xfer
->busy_free
!= XFER_FREE
) {
650 printf("uhci_allocx: xfer=%p not free, 0x%08x\n", xfer
,
655 xfer
= malloc(sizeof(struct uhci_xfer
), M_USB
, M_NOWAIT
);
658 memset(xfer
, 0, sizeof (struct uhci_xfer
));
659 UXFER(xfer
)->iinfo
.sc
= sc
;
661 UXFER(xfer
)->iinfo
.isdone
= 1;
662 xfer
->busy_free
= XFER_BUSY
;
669 uhci_freex(struct usbd_bus
*bus
, usbd_xfer_handle xfer
)
671 struct uhci_softc
*sc
= bus
->hci_private
;
674 if (xfer
->busy_free
!= XFER_BUSY
) {
675 printf("uhci_freex: xfer=%p not busy, 0x%08x\n", xfer
,
678 xfer
->busy_free
= XFER_FREE
;
679 if (!UXFER(xfer
)->iinfo
.isdone
) {
680 printf("uhci_freex: !isdone\n");
683 SIMPLEQ_INSERT_HEAD(&sc
->sc_free_xfers
, xfer
, next
);
687 * Handle suspend/resume.
689 * We need to switch to polling mode here, because this routine is
690 * called from an interrupt context. This is all right since we
691 * are almost suspended anyway.
694 uhci_resume(device_t dv
, pmf_qual_t qual
)
696 uhci_softc_t
*sc
= device_private(dv
);
702 cmd
= UREAD2(sc
, UHCI_CMD
);
703 sc
->sc_bus
.use_polling
++;
704 UWRITE2(sc
, UHCI_INTR
, 0);
705 uhci_globalreset(sc
);
707 if (cmd
& UHCI_CMD_RS
)
710 /* restore saved state */
711 UWRITE4(sc
, UHCI_FLBASEADDR
, DMAADDR(&sc
->sc_dma
, 0));
712 UWRITE2(sc
, UHCI_FRNUM
, sc
->sc_saved_frnum
);
713 UWRITE1(sc
, UHCI_SOF
, sc
->sc_saved_sof
);
715 UHCICMD(sc
, cmd
| UHCI_CMD_FGR
); /* force resume */
716 usb_delay_ms(&sc
->sc_bus
, USB_RESUME_DELAY
);
717 UHCICMD(sc
, cmd
& ~UHCI_CMD_EGSM
); /* back to normal */
718 UWRITE2(sc
, UHCI_INTR
, UHCI_INTR_TOCRCIE
|
719 UHCI_INTR_RIE
| UHCI_INTR_IOCE
| UHCI_INTR_SPIE
);
720 UHCICMD(sc
, UHCI_CMD_MAXP
);
721 uhci_run(sc
, 1); /* and start traffic again */
722 usb_delay_ms(&sc
->sc_bus
, USB_RESUME_RECOVERY
);
723 sc
->sc_bus
.use_polling
--;
724 if (sc
->sc_intr_xfer
!= NULL
)
725 usb_callout(sc
->sc_poll_handle
, sc
->sc_ival
, uhci_poll_hub
,
732 sc
->sc_suspend
= PWR_RESUME
;
739 uhci_suspend(device_t dv
, pmf_qual_t qual
)
741 uhci_softc_t
*sc
= device_private(dv
);
747 cmd
= UREAD2(sc
, UHCI_CMD
);
753 if (sc
->sc_intr_xfer
!= NULL
)
754 usb_uncallout(sc
->sc_poll_handle
, uhci_poll_hub
,
756 sc
->sc_suspend
= PWR_SUSPEND
;
757 sc
->sc_bus
.use_polling
++;
759 uhci_run(sc
, 0); /* stop the controller */
762 /* save some state if BIOS doesn't */
763 sc
->sc_saved_frnum
= UREAD2(sc
, UHCI_FRNUM
);
764 sc
->sc_saved_sof
= UREAD1(sc
, UHCI_SOF
);
766 UWRITE2(sc
, UHCI_INTR
, 0); /* disable intrs */
768 UHCICMD(sc
, cmd
| UHCI_CMD_EGSM
); /* enter suspend */
769 usb_delay_ms(&sc
->sc_bus
, USB_RESUME_WAIT
);
770 sc
->sc_bus
.use_polling
--;
779 uhci_dumpregs(uhci_softc_t
*sc
)
781 DPRINTFN(-1,("%s regs: cmd=%04x, sts=%04x, intr=%04x, frnum=%04x, "
782 "flbase=%08x, sof=%04x, portsc1=%04x, portsc2=%04x\n",
783 device_xname(sc
->sc_dev
),
784 UREAD2(sc
, UHCI_CMD
),
785 UREAD2(sc
, UHCI_STS
),
786 UREAD2(sc
, UHCI_INTR
),
787 UREAD2(sc
, UHCI_FRNUM
),
788 UREAD4(sc
, UHCI_FLBASEADDR
),
789 UREAD1(sc
, UHCI_SOF
),
790 UREAD2(sc
, UHCI_PORTSC1
),
791 UREAD2(sc
, UHCI_PORTSC2
)));
795 uhci_dump_td(uhci_soft_td_t
*p
)
797 char sbuf
[128], sbuf2
[128];
800 usb_syncmem(&p
->dma
, p
->offs
, sizeof(p
->td
),
801 BUS_DMASYNC_POSTWRITE
| BUS_DMASYNC_POSTREAD
);
802 DPRINTFN(-1,("TD(%p) at %08lx = link=0x%08lx status=0x%08lx "
803 "token=0x%08lx buffer=0x%08lx\n",
804 p
, (long)p
->physaddr
,
805 (long)le32toh(p
->td
.td_link
),
806 (long)le32toh(p
->td
.td_status
),
807 (long)le32toh(p
->td
.td_token
),
808 (long)le32toh(p
->td
.td_buffer
)));
810 snprintb(sbuf
, sizeof(sbuf
), "\20\1T\2Q\3VF",
811 (u_int32_t
)le32toh(p
->td
.td_link
));
812 snprintb(sbuf2
, sizeof(sbuf2
),
813 "\20\22BITSTUFF\23CRCTO\24NAK\25BABBLE\26DBUFFER\27"
814 "STALLED\30ACTIVE\31IOC\32ISO\33LS\36SPD",
815 (u_int32_t
)le32toh(p
->td
.td_status
));
817 DPRINTFN(-1,(" %s %s,errcnt=%d,actlen=%d pid=%02x,addr=%d,endpt=%d,"
818 "D=%d,maxlen=%d\n", sbuf
, sbuf2
,
819 UHCI_TD_GET_ERRCNT(le32toh(p
->td
.td_status
)),
820 UHCI_TD_GET_ACTLEN(le32toh(p
->td
.td_status
)),
821 UHCI_TD_GET_PID(le32toh(p
->td
.td_token
)),
822 UHCI_TD_GET_DEVADDR(le32toh(p
->td
.td_token
)),
823 UHCI_TD_GET_ENDPT(le32toh(p
->td
.td_token
)),
824 UHCI_TD_GET_DT(le32toh(p
->td
.td_token
)),
825 UHCI_TD_GET_MAXLEN(le32toh(p
->td
.td_token
))));
826 usb_syncmem(&p
->dma
, p
->offs
, sizeof(p
->td
),
827 BUS_DMASYNC_PREREAD
);
831 uhci_dump_qh(uhci_soft_qh_t
*sqh
)
833 usb_syncmem(&sqh
->dma
, sqh
->offs
, sizeof(sqh
->qh
),
834 BUS_DMASYNC_POSTWRITE
| BUS_DMASYNC_POSTREAD
);
835 DPRINTFN(-1,("QH(%p) at %08x: hlink=%08x elink=%08x\n", sqh
,
836 (int)sqh
->physaddr
, le32toh(sqh
->qh
.qh_hlink
),
837 le32toh(sqh
->qh
.qh_elink
)));
838 usb_syncmem(&sqh
->dma
, sqh
->offs
, sizeof(sqh
->qh
), BUS_DMASYNC_PREREAD
);
846 uhci_dump_all(thesc
);
851 uhci_dump_all(uhci_softc_t
*sc
)
854 printf("intrs=%d\n", sc
->sc_bus
.no_intrs
);
855 /*printf("framelist[i].link = %08x\n", sc->sc_framelist[0].link);*/
856 uhci_dump_qh(sc
->sc_lctl_start
);
861 uhci_dump_qhs(uhci_soft_qh_t
*sqh
)
865 /* uhci_dump_qhs displays all the QHs and TDs from the given QH onwards
866 * Traverses sideways first, then down.
876 * TD2.x being the TDs queued at QH2 and QH1 being referenced from QH1.
880 usb_syncmem(&sqh
->dma
, sqh
->offs
, sizeof(sqh
->qh
),
881 BUS_DMASYNC_POSTWRITE
| BUS_DMASYNC_POSTREAD
);
882 if (sqh
->hlink
!= NULL
&& !(le32toh(sqh
->qh
.qh_hlink
) & UHCI_PTR_T
))
883 uhci_dump_qhs(sqh
->hlink
);
885 DPRINTF(("No QH\n"));
886 usb_syncmem(&sqh
->dma
, sqh
->offs
, sizeof(sqh
->qh
), BUS_DMASYNC_PREREAD
);
888 if (sqh
->elink
!= NULL
&& !(le32toh(sqh
->qh
.qh_elink
) & UHCI_PTR_T
))
889 uhci_dump_tds(sqh
->elink
);
891 DPRINTF(("No TD\n"));
895 uhci_dump_tds(uhci_soft_td_t
*std
)
900 for(td
= std
; td
!= NULL
; td
= td
->link
.std
) {
903 /* Check whether the link pointer in this TD marks
904 * the link pointer as end of queue. This avoids
905 * printing the free list in case the queue/TD has
906 * already been moved there (seatbelt).
908 usb_syncmem(&td
->dma
, td
->offs
+ offsetof(uhci_td_t
, td_link
),
909 sizeof(td
->td
.td_link
),
910 BUS_DMASYNC_POSTWRITE
| BUS_DMASYNC_POSTREAD
);
911 stop
= (le32toh(td
->td
.td_link
) & UHCI_PTR_T
||
912 le32toh(td
->td
.td_link
) == 0);
913 usb_syncmem(&td
->dma
, td
->offs
+ offsetof(uhci_td_t
, td_link
),
914 sizeof(td
->td
.td_link
), BUS_DMASYNC_PREREAD
);
921 uhci_dump_ii(uhci_intr_info_t
*ii
)
923 usbd_pipe_handle pipe
;
924 usb_endpoint_descriptor_t
*ed
;
925 usbd_device_handle dev
;
928 #define DONE ii->isdone
936 if (ii
->xfer
== NULL
) {
937 printf("ii %p: done=%d xfer=NULL\n",
941 pipe
= ii
->xfer
->pipe
;
943 printf("ii %p: done=%d xfer=%p pipe=NULL\n",
947 if (pipe
->endpoint
== NULL
) {
948 printf("ii %p: done=%d xfer=%p pipe=%p pipe->endpoint=NULL\n",
949 ii
, DONE
, ii
->xfer
, pipe
);
952 if (pipe
->device
== NULL
) {
953 printf("ii %p: done=%d xfer=%p pipe=%p pipe->device=NULL\n",
954 ii
, DONE
, ii
->xfer
, pipe
);
957 ed
= pipe
->endpoint
->edesc
;
959 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",
960 ii
, DONE
, ii
->xfer
, dev
,
961 UGETW(dev
->ddesc
.idVendor
),
962 UGETW(dev
->ddesc
.idProduct
),
964 ed
->bEndpointAddress
, ed
->bmAttributes
);
968 void uhci_dump_iis(struct uhci_softc
*sc
);
970 uhci_dump_iis(struct uhci_softc
*sc
)
972 uhci_intr_info_t
*ii
;
974 printf("intr_info list:\n");
975 for (ii
= LIST_FIRST(&sc
->sc_intrhead
); ii
; ii
= LIST_NEXT(ii
, list
))
980 void iidump(void) { uhci_dump_iis(thesc
); }
985 * This routine is executed periodically and simulates interrupts
986 * from the root controller interrupt pipe for port status change.
989 uhci_poll_hub(void *addr
)
991 usbd_xfer_handle xfer
= addr
;
992 usbd_pipe_handle pipe
= xfer
->pipe
;
997 DPRINTFN(20, ("uhci_poll_hub\n"));
999 if (__predict_false(pipe
->device
== NULL
|| pipe
->device
->bus
== NULL
))
1000 return; /* device has detached */
1001 sc
= pipe
->device
->bus
->hci_private
;
1002 usb_callout(sc
->sc_poll_handle
, sc
->sc_ival
, uhci_poll_hub
, xfer
);
1004 p
= KERNADDR(&xfer
->dmabuf
, 0);
1006 if (UREAD2(sc
, UHCI_PORTSC1
) & (UHCI_PORTSC_CSC
|UHCI_PORTSC_OCIC
))
1008 if (UREAD2(sc
, UHCI_PORTSC2
) & (UHCI_PORTSC_CSC
|UHCI_PORTSC_OCIC
))
1011 /* No change, try again in a while */
1015 xfer
->status
= USBD_NORMAL_COMPLETION
;
1017 xfer
->device
->bus
->intr_context
++;
1018 usb_transfer_complete(xfer
);
1019 xfer
->device
->bus
->intr_context
--;
1024 uhci_root_intr_done(usbd_xfer_handle xfer
)
1029 uhci_root_ctrl_done(usbd_xfer_handle xfer
)
1034 * Let the last QH loop back to the high speed control transfer QH.
1035 * This is what intel calls "bandwidth reclamation" and improves
1036 * USB performance a lot for some devices.
1037 * If we are already looping, just count it.
1040 uhci_add_loop(uhci_softc_t
*sc
) {
1045 if (++sc
->sc_loops
== 1) {
1046 DPRINTFN(5,("uhci_start_loop: add\n"));
1047 /* Note, we don't loop back the soft pointer. */
1048 sc
->sc_last_qh
->qh
.qh_hlink
=
1049 htole32(sc
->sc_hctl_start
->physaddr
| UHCI_PTR_QH
);
1050 usb_syncmem(&sc
->sc_last_qh
->dma
,
1051 sc
->sc_last_qh
->offs
+ offsetof(uhci_qh_t
, qh_hlink
),
1052 sizeof(sc
->sc_last_qh
->qh
.qh_hlink
),
1053 BUS_DMASYNC_PREWRITE
);
1058 uhci_rem_loop(uhci_softc_t
*sc
) {
1063 if (--sc
->sc_loops
== 0) {
1064 DPRINTFN(5,("uhci_end_loop: remove\n"));
1065 sc
->sc_last_qh
->qh
.qh_hlink
= htole32(UHCI_PTR_T
);
1066 usb_syncmem(&sc
->sc_last_qh
->dma
,
1067 sc
->sc_last_qh
->offs
+ offsetof(uhci_qh_t
, qh_hlink
),
1068 sizeof(sc
->sc_last_qh
->qh
.qh_hlink
),
1069 BUS_DMASYNC_PREWRITE
);
1073 /* Add high speed control QH, called at splusb(). */
1075 uhci_add_hs_ctrl(uhci_softc_t
*sc
, uhci_soft_qh_t
*sqh
)
1077 uhci_soft_qh_t
*eqh
;
1081 DPRINTFN(10, ("uhci_add_ctrl: sqh=%p\n", sqh
));
1082 eqh
= sc
->sc_hctl_end
;
1083 usb_syncmem(&eqh
->dma
, eqh
->offs
+ offsetof(uhci_qh_t
, qh_hlink
),
1084 sizeof(eqh
->qh
.qh_hlink
),
1085 BUS_DMASYNC_POSTWRITE
);
1086 sqh
->hlink
= eqh
->hlink
;
1087 sqh
->qh
.qh_hlink
= eqh
->qh
.qh_hlink
;
1088 usb_syncmem(&sqh
->dma
, sqh
->offs
, sizeof(sqh
->qh
),
1089 BUS_DMASYNC_PREWRITE
);
1091 eqh
->qh
.qh_hlink
= htole32(sqh
->physaddr
| UHCI_PTR_QH
);
1092 sc
->sc_hctl_end
= sqh
;
1093 usb_syncmem(&eqh
->dma
, eqh
->offs
+ offsetof(uhci_qh_t
, qh_hlink
),
1094 sizeof(eqh
->qh
.qh_hlink
), BUS_DMASYNC_PREWRITE
);
1095 #ifdef UHCI_CTL_LOOP
1100 /* Remove high speed control QH, called at splusb(). */
1102 uhci_remove_hs_ctrl(uhci_softc_t
*sc
, uhci_soft_qh_t
*sqh
)
1104 uhci_soft_qh_t
*pqh
;
1108 DPRINTFN(10, ("uhci_remove_hs_ctrl: sqh=%p\n", sqh
));
1109 #ifdef UHCI_CTL_LOOP
1113 * The T bit should be set in the elink of the QH so that the HC
1114 * doesn't follow the pointer. This condition may fail if the
1115 * the transferred packet was short so that the QH still points
1116 * at the last used TD.
1117 * In this case we set the T bit and wait a little for the HC
1118 * to stop looking at the TD.
1119 * Note that if the TD chain is large enough, the controller
1120 * may still be looking at the chain at the end of this function.
1121 * uhci_free_std_chain() will make sure the controller stops
1122 * looking at it quickly, but until then we should not change
1125 usb_syncmem(&sqh
->dma
, sqh
->offs
+ offsetof(uhci_qh_t
, qh_elink
),
1126 sizeof(sqh
->qh
.qh_elink
),
1127 BUS_DMASYNC_POSTWRITE
| BUS_DMASYNC_POSTREAD
);
1128 if (!(sqh
->qh
.qh_elink
& htole32(UHCI_PTR_T
))) {
1129 sqh
->qh
.qh_elink
= htole32(UHCI_PTR_T
);
1130 usb_syncmem(&sqh
->dma
,
1131 sqh
->offs
+ offsetof(uhci_qh_t
, qh_elink
),
1132 sizeof(sqh
->qh
.qh_elink
),
1133 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
1134 delay(UHCI_QH_REMOVE_DELAY
);
1137 pqh
= uhci_find_prev_qh(sc
->sc_hctl_start
, sqh
);
1138 usb_syncmem(&sqh
->dma
, sqh
->offs
+ offsetof(uhci_qh_t
, qh_hlink
),
1139 sizeof(sqh
->qh
.qh_hlink
), BUS_DMASYNC_POSTWRITE
);
1140 pqh
->hlink
= sqh
->hlink
;
1141 pqh
->qh
.qh_hlink
= sqh
->qh
.qh_hlink
;
1142 usb_syncmem(&pqh
->dma
, pqh
->offs
+ offsetof(uhci_qh_t
, qh_hlink
),
1143 sizeof(pqh
->qh
.qh_hlink
),
1144 BUS_DMASYNC_PREWRITE
);
1145 delay(UHCI_QH_REMOVE_DELAY
);
1146 if (sc
->sc_hctl_end
== sqh
)
1147 sc
->sc_hctl_end
= pqh
;
1150 /* Add low speed control QH, called at splusb(). */
1152 uhci_add_ls_ctrl(uhci_softc_t
*sc
, uhci_soft_qh_t
*sqh
)
1154 uhci_soft_qh_t
*eqh
;
1158 DPRINTFN(10, ("uhci_add_ls_ctrl: sqh=%p\n", sqh
));
1159 eqh
= sc
->sc_lctl_end
;
1160 usb_syncmem(&eqh
->dma
, eqh
->offs
+ offsetof(uhci_qh_t
, qh_hlink
),
1161 sizeof(eqh
->qh
.qh_hlink
), BUS_DMASYNC_POSTWRITE
);
1162 sqh
->hlink
= eqh
->hlink
;
1163 sqh
->qh
.qh_hlink
= eqh
->qh
.qh_hlink
;
1164 usb_syncmem(&sqh
->dma
, sqh
->offs
, sizeof(sqh
->qh
),
1165 BUS_DMASYNC_PREWRITE
);
1167 eqh
->qh
.qh_hlink
= htole32(sqh
->physaddr
| UHCI_PTR_QH
);
1168 usb_syncmem(&eqh
->dma
, eqh
->offs
+ offsetof(uhci_qh_t
, qh_hlink
),
1169 sizeof(eqh
->qh
.qh_hlink
), BUS_DMASYNC_PREWRITE
);
1170 sc
->sc_lctl_end
= sqh
;
1173 /* Remove low speed control QH, called at splusb(). */
1175 uhci_remove_ls_ctrl(uhci_softc_t
*sc
, uhci_soft_qh_t
*sqh
)
1177 uhci_soft_qh_t
*pqh
;
1181 DPRINTFN(10, ("uhci_remove_ls_ctrl: sqh=%p\n", sqh
));
1182 /* See comment in uhci_remove_hs_ctrl() */
1183 usb_syncmem(&sqh
->dma
, sqh
->offs
+ offsetof(uhci_qh_t
, qh_elink
),
1184 sizeof(sqh
->qh
.qh_elink
),
1185 BUS_DMASYNC_POSTWRITE
| BUS_DMASYNC_POSTREAD
);
1186 if (!(sqh
->qh
.qh_elink
& htole32(UHCI_PTR_T
))) {
1187 sqh
->qh
.qh_elink
= htole32(UHCI_PTR_T
);
1188 usb_syncmem(&sqh
->dma
,
1189 sqh
->offs
+ offsetof(uhci_qh_t
, qh_elink
),
1190 sizeof(sqh
->qh
.qh_elink
),
1191 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
1192 delay(UHCI_QH_REMOVE_DELAY
);
1194 pqh
= uhci_find_prev_qh(sc
->sc_lctl_start
, sqh
);
1195 usb_syncmem(&sqh
->dma
, sqh
->offs
+ offsetof(uhci_qh_t
, qh_hlink
),
1196 sizeof(sqh
->qh
.qh_hlink
), BUS_DMASYNC_POSTWRITE
);
1197 pqh
->hlink
= sqh
->hlink
;
1198 pqh
->qh
.qh_hlink
= sqh
->qh
.qh_hlink
;
1199 usb_syncmem(&pqh
->dma
, pqh
->offs
+ offsetof(uhci_qh_t
, qh_hlink
),
1200 sizeof(pqh
->qh
.qh_hlink
),
1201 BUS_DMASYNC_PREWRITE
);
1202 delay(UHCI_QH_REMOVE_DELAY
);
1203 if (sc
->sc_lctl_end
== sqh
)
1204 sc
->sc_lctl_end
= pqh
;
1207 /* Add bulk QH, called at splusb(). */
1209 uhci_add_bulk(uhci_softc_t
*sc
, uhci_soft_qh_t
*sqh
)
1211 uhci_soft_qh_t
*eqh
;
1215 DPRINTFN(10, ("uhci_add_bulk: sqh=%p\n", sqh
));
1216 eqh
= sc
->sc_bulk_end
;
1217 usb_syncmem(&eqh
->dma
, eqh
->offs
+ offsetof(uhci_qh_t
, qh_hlink
),
1218 sizeof(eqh
->qh
.qh_hlink
), BUS_DMASYNC_POSTWRITE
);
1219 sqh
->hlink
= eqh
->hlink
;
1220 sqh
->qh
.qh_hlink
= eqh
->qh
.qh_hlink
;
1221 usb_syncmem(&sqh
->dma
, sqh
->offs
, sizeof(sqh
->qh
),
1222 BUS_DMASYNC_PREWRITE
);
1224 eqh
->qh
.qh_hlink
= htole32(sqh
->physaddr
| UHCI_PTR_QH
);
1225 usb_syncmem(&eqh
->dma
, eqh
->offs
+ offsetof(uhci_qh_t
, qh_hlink
),
1226 sizeof(eqh
->qh
.qh_hlink
), BUS_DMASYNC_PREWRITE
);
1227 sc
->sc_bulk_end
= sqh
;
1231 /* Remove bulk QH, called at splusb(). */
1233 uhci_remove_bulk(uhci_softc_t
*sc
, uhci_soft_qh_t
*sqh
)
1235 uhci_soft_qh_t
*pqh
;
1239 DPRINTFN(10, ("uhci_remove_bulk: sqh=%p\n", sqh
));
1241 /* See comment in uhci_remove_hs_ctrl() */
1242 usb_syncmem(&sqh
->dma
, sqh
->offs
+ offsetof(uhci_qh_t
, qh_elink
),
1243 sizeof(sqh
->qh
.qh_elink
),
1244 BUS_DMASYNC_POSTWRITE
| BUS_DMASYNC_POSTREAD
);
1245 if (!(sqh
->qh
.qh_elink
& htole32(UHCI_PTR_T
))) {
1246 sqh
->qh
.qh_elink
= htole32(UHCI_PTR_T
);
1247 usb_syncmem(&sqh
->dma
,
1248 sqh
->offs
+ offsetof(uhci_qh_t
, qh_elink
),
1249 sizeof(sqh
->qh
.qh_elink
),
1250 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
1251 delay(UHCI_QH_REMOVE_DELAY
);
1253 pqh
= uhci_find_prev_qh(sc
->sc_bulk_start
, sqh
);
1254 usb_syncmem(&sqh
->dma
, sqh
->offs
+ offsetof(uhci_qh_t
, qh_hlink
),
1255 sizeof(sqh
->qh
.qh_hlink
), BUS_DMASYNC_POSTWRITE
);
1256 pqh
->hlink
= sqh
->hlink
;
1257 pqh
->qh
.qh_hlink
= sqh
->qh
.qh_hlink
;
1258 usb_syncmem(&pqh
->dma
, pqh
->offs
+ offsetof(uhci_qh_t
, qh_hlink
),
1259 sizeof(pqh
->qh
.qh_hlink
), BUS_DMASYNC_PREWRITE
);
1260 delay(UHCI_QH_REMOVE_DELAY
);
1261 if (sc
->sc_bulk_end
== sqh
)
1262 sc
->sc_bulk_end
= pqh
;
1265 Static
int uhci_intr1(uhci_softc_t
*);
1268 uhci_intr(void *arg
)
1270 uhci_softc_t
*sc
= arg
;
1272 if (sc
->sc_dying
|| !device_has_power(sc
->sc_dev
))
1275 if (sc
->sc_bus
.use_polling
|| UREAD2(sc
, UHCI_INTR
) == 0) {
1277 DPRINTFN(16, ("uhci_intr: ignored interrupt while polling\n"));
1282 return (uhci_intr1(sc
));
1286 uhci_intr1(uhci_softc_t
*sc
)
1292 if (uhcidebug
> 15) {
1293 DPRINTF(("%s: uhci_intr1\n", device_xname(sc
->sc_dev
)));
1298 status
= UREAD2(sc
, UHCI_STS
) & UHCI_STS_ALLINTRS
;
1299 if (status
== 0) /* The interrupt was not for us. */
1302 if (sc
->sc_suspend
!= PWR_RESUME
) {
1304 printf("%s: interrupt while not operating ignored\n",
1305 device_xname(sc
->sc_dev
));
1307 UWRITE2(sc
, UHCI_STS
, status
); /* acknowledge the ints */
1312 if (status
& UHCI_STS_USBINT
)
1313 ack
|= UHCI_STS_USBINT
;
1314 if (status
& UHCI_STS_USBEI
)
1315 ack
|= UHCI_STS_USBEI
;
1316 if (status
& UHCI_STS_RD
) {
1319 printf("%s: resume detect\n", device_xname(sc
->sc_dev
));
1322 if (status
& UHCI_STS_HSE
) {
1323 ack
|= UHCI_STS_HSE
;
1324 printf("%s: host system error\n", device_xname(sc
->sc_dev
));
1326 if (status
& UHCI_STS_HCPE
) {
1327 ack
|= UHCI_STS_HCPE
;
1328 printf("%s: host controller process error\n",
1329 device_xname(sc
->sc_dev
));
1331 if (status
& UHCI_STS_HCH
) {
1332 /* no acknowledge needed */
1333 if (!sc
->sc_dying
) {
1334 printf("%s: host controller halted\n",
1335 device_xname(sc
->sc_dev
));
1344 return (0); /* nothing to acknowledge */
1345 UWRITE2(sc
, UHCI_STS
, ack
); /* acknowledge the ints */
1347 sc
->sc_bus
.no_intrs
++;
1348 usb_schedsoftintr(&sc
->sc_bus
);
1350 DPRINTFN(15, ("%s: uhci_intr: exit\n", device_xname(sc
->sc_dev
)));
1356 uhci_softintr(void *v
)
1358 struct usbd_bus
*bus
= v
;
1359 uhci_softc_t
*sc
= bus
->hci_private
;
1360 uhci_intr_info_t
*ii
, *nextii
;
1362 DPRINTFN(10,("%s: uhci_softintr (%d)\n", device_xname(sc
->sc_dev
),
1363 sc
->sc_bus
.intr_context
));
1365 sc
->sc_bus
.intr_context
++;
1368 * Interrupts on UHCI really suck. When the host controller
1369 * interrupts because a transfer is completed there is no
1370 * way of knowing which transfer it was. You can scan down
1371 * the TDs and QHs of the previous frame to limit the search,
1372 * but that assumes that the interrupt was not delayed by more
1373 * than 1 ms, which may not always be true (e.g. after debug
1374 * output on a slow console).
1375 * We scan all interrupt descriptors to see if any have
1378 for (ii
= LIST_FIRST(&sc
->sc_intrhead
); ii
; ii
= nextii
) {
1379 nextii
= LIST_NEXT(ii
, list
);
1380 uhci_check_intr(sc
, ii
);
1383 #ifdef USB_USE_SOFTINTR
1384 if (sc
->sc_softwake
) {
1385 sc
->sc_softwake
= 0;
1386 wakeup(&sc
->sc_softwake
);
1388 #endif /* USB_USE_SOFTINTR */
1390 sc
->sc_bus
.intr_context
--;
1393 /* Check for an interrupt. */
1395 uhci_check_intr(uhci_softc_t
*sc
, uhci_intr_info_t
*ii
)
1397 uhci_soft_td_t
*std
, *lstd
;
1400 DPRINTFN(15, ("uhci_check_intr: ii=%p\n", ii
));
1403 printf("uhci_check_intr: no ii? %p\n", ii
);
1407 if (ii
->xfer
->status
== USBD_CANCELLED
||
1408 ii
->xfer
->status
== USBD_TIMEOUT
) {
1409 DPRINTF(("uhci_check_intr: aborted xfer=%p\n", ii
->xfer
));
1413 if (ii
->stdstart
== NULL
)
1418 printf("uhci_check_intr: std==0\n");
1423 * If the last TD is still active we need to check whether there
1424 * is an error somewhere in the middle, or whether there was a
1425 * short packet (SPD and not ACTIVE).
1427 usb_syncmem(&lstd
->dma
,
1428 lstd
->offs
+ offsetof(uhci_td_t
, td_status
),
1429 sizeof(lstd
->td
.td_status
),
1430 BUS_DMASYNC_POSTWRITE
| BUS_DMASYNC_POSTREAD
);
1431 if (le32toh(lstd
->td
.td_status
) & UHCI_TD_ACTIVE
) {
1432 DPRINTFN(12, ("uhci_check_intr: active ii=%p\n", ii
));
1433 for (std
= ii
->stdstart
; std
!= lstd
; std
= std
->link
.std
) {
1434 usb_syncmem(&std
->dma
,
1435 std
->offs
+ offsetof(uhci_td_t
, td_status
),
1436 sizeof(std
->td
.td_status
),
1437 BUS_DMASYNC_POSTWRITE
| BUS_DMASYNC_POSTREAD
);
1438 status
= le32toh(std
->td
.td_status
);
1439 usb_syncmem(&std
->dma
,
1440 std
->offs
+ offsetof(uhci_td_t
, td_status
),
1441 sizeof(std
->td
.td_status
), BUS_DMASYNC_PREREAD
);
1442 /* If there's an active TD the xfer isn't done. */
1443 if (status
& UHCI_TD_ACTIVE
)
1445 /* Any kind of error makes the xfer done. */
1446 if (status
& UHCI_TD_STALLED
)
1448 /* We want short packets, and it is short: it's done */
1449 usb_syncmem(&std
->dma
,
1450 std
->offs
+ offsetof(uhci_td_t
, td_token
),
1451 sizeof(std
->td
.td_token
),
1452 BUS_DMASYNC_POSTWRITE
);
1453 if ((status
& UHCI_TD_SPD
) &&
1454 UHCI_TD_GET_ACTLEN(status
) <
1455 UHCI_TD_GET_MAXLEN(le32toh(std
->td
.td_token
)))
1458 DPRINTFN(12, ("uhci_check_intr: ii=%p std=%p still active\n",
1460 usb_syncmem(&lstd
->dma
,
1461 lstd
->offs
+ offsetof(uhci_td_t
, td_status
),
1462 sizeof(lstd
->td
.td_status
),
1463 BUS_DMASYNC_PREREAD
);
1467 DPRINTFN(12, ("uhci_check_intr: ii=%p done\n", ii
));
1468 usb_uncallout(ii
->xfer
->timeout_handle
, uhci_timeout
, ii
);
1472 /* Called at splusb() */
1474 uhci_idone(uhci_intr_info_t
*ii
)
1476 usbd_xfer_handle xfer
= ii
->xfer
;
1477 struct uhci_pipe
*upipe
= (struct uhci_pipe
*)xfer
->pipe
;
1478 uhci_soft_td_t
*std
;
1479 u_int32_t status
= 0, nstatus
;
1482 DPRINTFN(12, ("uhci_idone: ii=%p\n", ii
));
1489 printf("uhci_idone: ii is done!\n ");
1492 printf("uhci_idone: ii=%p is done!\n", ii
);
1501 if (xfer
->nframes
!= 0) {
1502 /* Isoc transfer, do things differently. */
1503 uhci_soft_td_t
**stds
= upipe
->u
.iso
.stds
;
1504 int i
, n
, nframes
, len
;
1506 DPRINTFN(5,("uhci_idone: ii=%p isoc ready\n", ii
));
1508 nframes
= xfer
->nframes
;
1510 n
= UXFER(xfer
)->curframe
;
1511 for (i
= 0; i
< nframes
; i
++) {
1514 if (uhcidebug
> 5) {
1515 DPRINTFN(-1,("uhci_idone: isoc TD %d\n", i
));
1519 if (++n
>= UHCI_VFRAMELIST_COUNT
)
1521 usb_syncmem(&std
->dma
,
1522 std
->offs
+ offsetof(uhci_td_t
, td_status
),
1523 sizeof(std
->td
.td_status
),
1524 BUS_DMASYNC_POSTWRITE
| BUS_DMASYNC_POSTREAD
);
1525 status
= le32toh(std
->td
.td_status
);
1526 len
= UHCI_TD_GET_ACTLEN(status
);
1527 xfer
->frlengths
[i
] = len
;
1530 upipe
->u
.iso
.inuse
-= nframes
;
1531 xfer
->actlen
= actlen
;
1532 xfer
->status
= USBD_NORMAL_COMPLETION
;
1537 DPRINTFN(10, ("uhci_idone: ii=%p, xfer=%p, pipe=%p ready\n",
1540 uhci_dump_tds(ii
->stdstart
);
1543 /* The transfer is done, compute actual length and status. */
1545 for (std
= ii
->stdstart
; std
!= NULL
; std
= std
->link
.std
) {
1546 usb_syncmem(&std
->dma
, std
->offs
, sizeof(std
->td
),
1547 BUS_DMASYNC_POSTWRITE
| BUS_DMASYNC_POSTREAD
);
1548 nstatus
= le32toh(std
->td
.td_status
);
1549 if (nstatus
& UHCI_TD_ACTIVE
)
1553 if (UHCI_TD_GET_PID(le32toh(std
->td
.td_token
)) !=
1555 actlen
+= UHCI_TD_GET_ACTLEN(status
);
1558 * UHCI will report CRCTO in addition to a STALL or NAK
1559 * for a SETUP transaction. See section 3.2.2, "TD
1560 * CONTROL AND STATUS".
1562 if (status
& (UHCI_TD_STALLED
| UHCI_TD_NAK
))
1563 status
&= ~UHCI_TD_CRCTO
;
1566 /* If there are left over TDs we need to update the toggle. */
1568 upipe
->nexttoggle
= UHCI_TD_GET_DT(le32toh(std
->td
.td_token
));
1570 status
&= UHCI_TD_ERROR
;
1571 DPRINTFN(10, ("uhci_idone: actlen=%d, status=0x%x\n",
1573 xfer
->actlen
= actlen
;
1578 snprintb(sbuf
, sizeof(sbuf
),
1579 "\20\22BITSTUFF\23CRCTO\24NAK\25"
1580 "BABBLE\26DBUFFER\27STALLED\30ACTIVE",(u_int32_t
)status
);
1582 DPRINTFN((status
== UHCI_TD_STALLED
)*10,
1583 ("uhci_idone: error, addr=%d, endpt=0x%02x, "
1585 xfer
->pipe
->device
->address
,
1586 xfer
->pipe
->endpoint
->edesc
->bEndpointAddress
,
1590 if (status
== UHCI_TD_STALLED
)
1591 xfer
->status
= USBD_STALLED
;
1593 xfer
->status
= USBD_IOERROR
; /* more info XXX */
1595 xfer
->status
= USBD_NORMAL_COMPLETION
;
1599 usb_transfer_complete(xfer
);
1600 DPRINTFN(12, ("uhci_idone: ii=%p done\n", ii
));
1604 * Called when a request does not complete.
1607 uhci_timeout(void *addr
)
1609 uhci_intr_info_t
*ii
= addr
;
1610 struct uhci_xfer
*uxfer
= UXFER(ii
->xfer
);
1611 struct uhci_pipe
*upipe
= (struct uhci_pipe
*)uxfer
->xfer
.pipe
;
1612 uhci_softc_t
*sc
= upipe
->pipe
.device
->bus
->hci_private
;
1614 DPRINTF(("uhci_timeout: uxfer=%p\n", uxfer
));
1617 uhci_abort_xfer(&uxfer
->xfer
, USBD_TIMEOUT
);
1621 /* Execute the abort in a process context. */
1622 usb_init_task(&uxfer
->abort_task
, uhci_timeout_task
, ii
->xfer
);
1623 usb_add_task(uxfer
->xfer
.pipe
->device
, &uxfer
->abort_task
,
1628 uhci_timeout_task(void *addr
)
1630 usbd_xfer_handle xfer
= addr
;
1633 DPRINTF(("uhci_timeout_task: xfer=%p\n", xfer
));
1636 uhci_abort_xfer(xfer
, USBD_TIMEOUT
);
1641 * Wait here until controller claims to have an interrupt.
1642 * Then call uhci_intr and return. Use timeout to avoid waiting
1644 * Only used during boot when interrupts are not enabled yet.
1647 uhci_waitintr(uhci_softc_t
*sc
, usbd_xfer_handle xfer
)
1649 int timo
= xfer
->timeout
;
1650 uhci_intr_info_t
*ii
;
1652 DPRINTFN(10,("uhci_waitintr: timeout = %dms\n", timo
));
1654 xfer
->status
= USBD_IN_PROGRESS
;
1655 for (; timo
>= 0; timo
--) {
1656 usb_delay_ms(&sc
->sc_bus
, 1);
1657 DPRINTFN(20,("uhci_waitintr: 0x%04x\n", UREAD2(sc
, UHCI_STS
)));
1658 if (UREAD2(sc
, UHCI_STS
) & UHCI_STS_USBINT
) {
1660 if (xfer
->status
!= USBD_IN_PROGRESS
)
1666 DPRINTF(("uhci_waitintr: timeout\n"));
1667 for (ii
= LIST_FIRST(&sc
->sc_intrhead
);
1668 ii
!= NULL
&& ii
->xfer
!= xfer
;
1669 ii
= LIST_NEXT(ii
, list
))
1673 panic("uhci_waitintr: lost intr_info");
1679 uhci_poll(struct usbd_bus
*bus
)
1681 uhci_softc_t
*sc
= bus
->hci_private
;
1683 if (UREAD2(sc
, UHCI_STS
) & UHCI_STS_USBINT
)
1688 uhci_reset(uhci_softc_t
*sc
)
1692 UHCICMD(sc
, UHCI_CMD_HCRESET
);
1693 /* The reset bit goes low when the controller is done. */
1694 for (n
= 0; n
< UHCI_RESET_TIMEOUT
&&
1695 (UREAD2(sc
, UHCI_CMD
) & UHCI_CMD_HCRESET
); n
++)
1696 usb_delay_ms(&sc
->sc_bus
, 1);
1697 if (n
>= UHCI_RESET_TIMEOUT
)
1698 printf("%s: controller did not reset\n",
1699 device_xname(sc
->sc_dev
));
1703 uhci_run(uhci_softc_t
*sc
, int run
)
1710 DPRINTF(("uhci_run: setting run=%d\n", run
));
1711 cmd
= UREAD2(sc
, UHCI_CMD
);
1715 cmd
&= ~UHCI_CMD_RS
;
1717 for(n
= 0; n
< 10; n
++) {
1718 running
= !(UREAD2(sc
, UHCI_STS
) & UHCI_STS_HCH
);
1719 /* return when we've entered the state we want */
1720 if (run
== running
) {
1722 DPRINTF(("uhci_run: done cmd=0x%x sts=0x%x\n",
1723 UREAD2(sc
, UHCI_CMD
), UREAD2(sc
, UHCI_STS
)));
1724 return (USBD_NORMAL_COMPLETION
);
1726 usb_delay_ms(&sc
->sc_bus
, 1);
1729 printf("%s: cannot %s\n", device_xname(sc
->sc_dev
),
1730 run
? "start" : "stop");
1731 return (USBD_IOERROR
);
1735 * Memory management routines.
1736 * uhci_alloc_std allocates TDs
1737 * uhci_alloc_sqh allocates QHs
1738 * These two routines do their own free list management,
1739 * partly for speed, partly because allocating DMAable memory
1740 * has page size granularaity so much memory would be wasted if
1741 * only one TD/QH (32 bytes) was placed in each allocated chunk.
1745 uhci_alloc_std(uhci_softc_t
*sc
)
1747 uhci_soft_td_t
*std
;
1752 if (sc
->sc_freetds
== NULL
) {
1753 DPRINTFN(2,("uhci_alloc_std: allocating chunk\n"));
1754 err
= usb_allocmem(&sc
->sc_bus
, UHCI_STD_SIZE
* UHCI_STD_CHUNK
,
1755 UHCI_TD_ALIGN
, &dma
);
1758 for(i
= 0; i
< UHCI_STD_CHUNK
; i
++) {
1759 offs
= i
* UHCI_STD_SIZE
;
1760 std
= KERNADDR(&dma
, offs
);
1761 std
->physaddr
= DMAADDR(&dma
, offs
);
1764 std
->link
.std
= sc
->sc_freetds
;
1765 sc
->sc_freetds
= std
;
1768 std
= sc
->sc_freetds
;
1769 sc
->sc_freetds
= std
->link
.std
;
1770 memset(&std
->td
, 0, sizeof(uhci_td_t
));
1775 uhci_free_std(uhci_softc_t
*sc
, uhci_soft_td_t
*std
)
1778 #define TD_IS_FREE 0x12345678
1779 if (le32toh(std
->td
.td_token
) == TD_IS_FREE
) {
1780 printf("uhci_free_std: freeing free TD %p\n", std
);
1783 std
->td
.td_token
= htole32(TD_IS_FREE
);
1785 std
->link
.std
= sc
->sc_freetds
;
1786 sc
->sc_freetds
= std
;
1790 uhci_alloc_sqh(uhci_softc_t
*sc
)
1792 uhci_soft_qh_t
*sqh
;
1797 if (sc
->sc_freeqhs
== NULL
) {
1798 DPRINTFN(2, ("uhci_alloc_sqh: allocating chunk\n"));
1799 err
= usb_allocmem(&sc
->sc_bus
, UHCI_SQH_SIZE
* UHCI_SQH_CHUNK
,
1800 UHCI_QH_ALIGN
, &dma
);
1803 for(i
= 0; i
< UHCI_SQH_CHUNK
; i
++) {
1804 offs
= i
* UHCI_SQH_SIZE
;
1805 sqh
= KERNADDR(&dma
, offs
);
1806 sqh
->physaddr
= DMAADDR(&dma
, offs
);
1809 sqh
->hlink
= sc
->sc_freeqhs
;
1810 sc
->sc_freeqhs
= sqh
;
1813 sqh
= sc
->sc_freeqhs
;
1814 sc
->sc_freeqhs
= sqh
->hlink
;
1815 memset(&sqh
->qh
, 0, sizeof(uhci_qh_t
));
1820 uhci_free_sqh(uhci_softc_t
*sc
, uhci_soft_qh_t
*sqh
)
1822 sqh
->hlink
= sc
->sc_freeqhs
;
1823 sc
->sc_freeqhs
= sqh
;
1827 uhci_free_std_chain(uhci_softc_t
*sc
, uhci_soft_td_t
*std
,
1828 uhci_soft_td_t
*stdend
)
1833 * to avoid race condition with the controller which may be looking
1834 * at this chain, we need to first invalidate all links, and
1835 * then wait for the controller to move to another queue
1837 for (p
= std
; p
!= stdend
; p
= p
->link
.std
) {
1838 usb_syncmem(&p
->dma
,
1839 p
->offs
+ offsetof(uhci_td_t
, td_link
),
1840 sizeof(p
->td
.td_link
),
1841 BUS_DMASYNC_POSTWRITE
| BUS_DMASYNC_POSTREAD
);
1842 if ((p
->td
.td_link
& UHCI_PTR_T
) == 0) {
1843 p
->td
.td_link
= UHCI_PTR_T
;
1844 usb_syncmem(&p
->dma
,
1845 p
->offs
+ offsetof(uhci_td_t
, td_link
),
1846 sizeof(p
->td
.td_link
),
1847 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
1850 delay(UHCI_QH_REMOVE_DELAY
);
1852 for (; std
!= stdend
; std
= p
) {
1854 uhci_free_std(sc
, std
);
1859 uhci_alloc_std_chain(struct uhci_pipe
*upipe
, uhci_softc_t
*sc
, int len
,
1860 int rd
, u_int16_t flags
, usb_dma_t
*dma
,
1861 uhci_soft_td_t
**sp
, uhci_soft_td_t
**ep
)
1863 uhci_soft_td_t
*p
, *lastp
;
1864 uhci_physaddr_t lastlink
;
1865 int i
, ntd
, l
, tog
, maxp
;
1867 int addr
= upipe
->pipe
.device
->address
;
1868 int endpt
= upipe
->pipe
.endpoint
->edesc
->bEndpointAddress
;
1870 DPRINTFN(8, ("uhci_alloc_std_chain: addr=%d endpt=%d len=%d speed=%d "
1871 "flags=0x%x\n", addr
, UE_GET_ADDR(endpt
), len
,
1872 upipe
->pipe
.device
->speed
, flags
));
1873 maxp
= UGETW(upipe
->pipe
.endpoint
->edesc
->wMaxPacketSize
);
1875 printf("uhci_alloc_std_chain: maxp=0\n");
1876 return (USBD_INVAL
);
1878 ntd
= (len
+ maxp
- 1) / maxp
;
1879 if ((flags
& USBD_FORCE_SHORT_XFER
) && len
% maxp
== 0)
1881 DPRINTFN(10, ("uhci_alloc_std_chain: maxp=%d ntd=%d\n", maxp
, ntd
));
1884 DPRINTFN(-1,("uhci_alloc_std_chain: ntd=0\n"));
1885 return (USBD_NORMAL_COMPLETION
);
1887 tog
= upipe
->nexttoggle
;
1890 upipe
->nexttoggle
= tog
^ 1;
1892 lastlink
= UHCI_PTR_T
;
1894 status
= UHCI_TD_ZERO_ACTLEN(UHCI_TD_SET_ERRCNT(3) | UHCI_TD_ACTIVE
);
1895 if (upipe
->pipe
.device
->speed
== USB_SPEED_LOW
)
1896 status
|= UHCI_TD_LS
;
1897 if (flags
& USBD_SHORT_XFER_OK
)
1898 status
|= UHCI_TD_SPD
;
1899 usb_syncmem(dma
, 0, len
,
1900 rd
? BUS_DMASYNC_PREREAD
: BUS_DMASYNC_PREWRITE
);
1901 for (i
= ntd
; i
>= 0; i
--) {
1902 p
= uhci_alloc_std(sc
);
1904 KASSERT(lastp
!= NULL
);
1905 uhci_free_std_chain(sc
, lastp
, NULL
);
1906 return (USBD_NOMEM
);
1908 p
->link
.std
= lastp
;
1909 p
->td
.td_link
= htole32(lastlink
| UHCI_PTR_VF
| UHCI_PTR_TD
);
1911 lastlink
= p
->physaddr
;
1912 p
->td
.td_status
= htole32(status
);
1916 if (l
== 0 && !(flags
& USBD_FORCE_SHORT_XFER
))
1922 htole32(rd
? UHCI_TD_IN (l
, endpt
, addr
, tog
) :
1923 UHCI_TD_OUT(l
, endpt
, addr
, tog
));
1924 p
->td
.td_buffer
= htole32(DMAADDR(dma
, i
* maxp
));
1925 usb_syncmem(&p
->dma
, p
->offs
, sizeof(p
->td
),
1926 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
1930 DPRINTFN(10, ("uhci_alloc_std_chain: nexttog=%d\n",
1931 upipe
->nexttoggle
));
1932 return (USBD_NORMAL_COMPLETION
);
1936 uhci_device_clear_toggle(usbd_pipe_handle pipe
)
1938 struct uhci_pipe
*upipe
= (struct uhci_pipe
*)pipe
;
1939 upipe
->nexttoggle
= 0;
1943 uhci_noop(usbd_pipe_handle pipe
)
1948 uhci_device_bulk_transfer(usbd_xfer_handle xfer
)
1952 /* Insert last in queue. */
1953 err
= usb_insert_transfer(xfer
);
1958 * Pipe isn't running (otherwise err would be USBD_INPROG),
1959 * so start it first.
1961 return (uhci_device_bulk_start(SIMPLEQ_FIRST(&xfer
->pipe
->queue
)));
1965 uhci_device_bulk_start(usbd_xfer_handle xfer
)
1967 struct uhci_pipe
*upipe
= (struct uhci_pipe
*)xfer
->pipe
;
1968 usbd_device_handle dev
= upipe
->pipe
.device
;
1969 uhci_softc_t
*sc
= dev
->bus
->hci_private
;
1970 uhci_intr_info_t
*ii
= &UXFER(xfer
)->iinfo
;
1971 uhci_soft_td_t
*data
, *dataend
;
1972 uhci_soft_qh_t
*sqh
;
1974 int len
, isread
, endpt
;
1977 DPRINTFN(3, ("uhci_device_bulk_start: xfer=%p len=%d flags=%d ii=%p\n",
1978 xfer
, xfer
->length
, xfer
->flags
, ii
));
1981 return (USBD_IOERROR
);
1984 if (xfer
->rqflags
& URQ_REQUEST
)
1985 panic("uhci_device_bulk_transfer: a request");
1989 endpt
= upipe
->pipe
.endpoint
->edesc
->bEndpointAddress
;
1990 isread
= UE_GET_DIR(endpt
) == UE_DIR_IN
;
1991 sqh
= upipe
->u
.bulk
.sqh
;
1993 upipe
->u
.bulk
.isread
= isread
;
1994 upipe
->u
.bulk
.length
= len
;
1996 err
= uhci_alloc_std_chain(upipe
, sc
, len
, isread
, xfer
->flags
,
1997 &xfer
->dmabuf
, &data
, &dataend
);
2000 dataend
->td
.td_status
|= htole32(UHCI_TD_IOC
);
2001 usb_syncmem(&dataend
->dma
,
2002 dataend
->offs
+ offsetof(uhci_td_t
, td_status
),
2003 sizeof(dataend
->td
.td_status
),
2004 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
2008 if (uhcidebug
> 8) {
2009 DPRINTF(("uhci_device_bulk_transfer: data(1)\n"));
2010 uhci_dump_tds(data
);
2014 /* Set up interrupt info. */
2016 ii
->stdstart
= data
;
2017 ii
->stdend
= dataend
;
2020 printf("uhci_device_bulk_transfer: not done, ii=%p\n", ii
);
2026 sqh
->qh
.qh_elink
= htole32(data
->physaddr
| UHCI_PTR_TD
);
2027 /* uhci_add_bulk() will do usb_syncmem(sqh) */
2030 uhci_add_bulk(sc
, sqh
);
2031 uhci_add_intr_info(sc
, ii
);
2033 if (xfer
->timeout
&& !sc
->sc_bus
.use_polling
) {
2034 usb_callout(xfer
->timeout_handle
, mstohz(xfer
->timeout
),
2037 xfer
->status
= USBD_IN_PROGRESS
;
2041 if (uhcidebug
> 10) {
2042 DPRINTF(("uhci_device_bulk_transfer: data(2)\n"));
2043 uhci_dump_tds(data
);
2047 if (sc
->sc_bus
.use_polling
)
2048 uhci_waitintr(sc
, xfer
);
2050 return (USBD_IN_PROGRESS
);
2053 /* Abort a device bulk request. */
2055 uhci_device_bulk_abort(usbd_xfer_handle xfer
)
2057 DPRINTF(("uhci_device_bulk_abort:\n"));
2058 uhci_abort_xfer(xfer
, USBD_CANCELLED
);
2062 * Abort a device request.
2063 * If this routine is called at splusb() it guarantees that the request
2064 * will be removed from the hardware scheduling and that the callback
2065 * for it will be called with USBD_CANCELLED status.
2066 * It's impossible to guarantee that the requested transfer will not
2067 * have happened since the hardware runs concurrently.
2068 * If the transaction has already happened we rely on the ordinary
2069 * interrupt processing to process it.
2072 uhci_abort_xfer(usbd_xfer_handle xfer
, usbd_status status
)
2074 uhci_intr_info_t
*ii
= &UXFER(xfer
)->iinfo
;
2075 struct uhci_pipe
*upipe
= (struct uhci_pipe
*)xfer
->pipe
;
2076 uhci_softc_t
*sc
= upipe
->pipe
.device
->bus
->hci_private
;
2077 uhci_soft_td_t
*std
;
2081 DPRINTFN(1,("uhci_abort_xfer: xfer=%p, status=%d\n", xfer
, status
));
2084 /* If we're dying, just do the software part. */
2086 xfer
->status
= status
; /* make software ignore it */
2087 usb_uncallout(xfer
->timeout_handle
, uhci_timeout
, xfer
);
2088 usb_transfer_complete(xfer
);
2093 if (xfer
->device
->bus
->intr_context
|| !curproc
)
2094 panic("uhci_abort_xfer: not in process context");
2097 * If an abort is already in progress then just wait for it to
2098 * complete and return.
2100 if (xfer
->hcflags
& UXFER_ABORTING
) {
2101 DPRINTFN(2, ("uhci_abort_xfer: already aborting\n"));
2103 if (status
== USBD_TIMEOUT
)
2104 printf("uhci_abort_xfer: TIMEOUT while aborting\n");
2106 /* Override the status which might be USBD_TIMEOUT. */
2107 xfer
->status
= status
;
2108 DPRINTFN(2, ("uhci_abort_xfer: waiting for abort to finish\n"));
2109 xfer
->hcflags
|= UXFER_ABORTWAIT
;
2110 while (xfer
->hcflags
& UXFER_ABORTING
)
2111 tsleep(&xfer
->hcflags
, PZERO
, "uhciaw", 0);
2114 xfer
->hcflags
|= UXFER_ABORTING
;
2117 * Step 1: Make interrupt routine and hardware ignore xfer.
2120 xfer
->status
= status
; /* make software ignore it */
2121 usb_uncallout(xfer
->timeout_handle
, uhci_timeout
, ii
);
2122 DPRINTFN(1,("uhci_abort_xfer: stop ii=%p\n", ii
));
2123 for (std
= ii
->stdstart
; std
!= NULL
; std
= std
->link
.std
) {
2124 usb_syncmem(&std
->dma
,
2125 std
->offs
+ offsetof(uhci_td_t
, td_status
),
2126 sizeof(std
->td
.td_status
),
2127 BUS_DMASYNC_POSTWRITE
| BUS_DMASYNC_POSTREAD
);
2128 std
->td
.td_status
&= htole32(~(UHCI_TD_ACTIVE
| UHCI_TD_IOC
));
2129 usb_syncmem(&std
->dma
,
2130 std
->offs
+ offsetof(uhci_td_t
, td_status
),
2131 sizeof(std
->td
.td_status
),
2132 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
2137 * Step 2: Wait until we know hardware has finished any possible
2138 * use of the xfer. Also make sure the soft interrupt routine
2141 usb_delay_ms(upipe
->pipe
.device
->bus
, 2); /* Hardware finishes in 1ms */
2143 #ifdef USB_USE_SOFTINTR
2144 sc
->sc_softwake
= 1;
2145 #endif /* USB_USE_SOFTINTR */
2146 usb_schedsoftintr(&sc
->sc_bus
);
2147 #ifdef USB_USE_SOFTINTR
2148 DPRINTFN(1,("uhci_abort_xfer: tsleep\n"));
2149 tsleep(&sc
->sc_softwake
, PZERO
, "uhciab", 0);
2150 #endif /* USB_USE_SOFTINTR */
2154 * Step 3: Execute callback.
2156 DPRINTFN(1,("uhci_abort_xfer: callback\n"));
2161 wake
= xfer
->hcflags
& UXFER_ABORTWAIT
;
2162 xfer
->hcflags
&= ~(UXFER_ABORTING
| UXFER_ABORTWAIT
);
2163 usb_transfer_complete(xfer
);
2165 wakeup(&xfer
->hcflags
);
2169 /* Close a device bulk pipe. */
2171 uhci_device_bulk_close(usbd_pipe_handle pipe
)
2173 struct uhci_pipe
*upipe
= (struct uhci_pipe
*)pipe
;
2174 usbd_device_handle dev
= upipe
->pipe
.device
;
2175 uhci_softc_t
*sc
= dev
->bus
->hci_private
;
2177 uhci_free_sqh(sc
, upipe
->u
.bulk
.sqh
);
2181 uhci_device_ctrl_transfer(usbd_xfer_handle xfer
)
2185 /* Insert last in queue. */
2186 err
= usb_insert_transfer(xfer
);
2191 * Pipe isn't running (otherwise err would be USBD_INPROG),
2192 * so start it first.
2194 return (uhci_device_ctrl_start(SIMPLEQ_FIRST(&xfer
->pipe
->queue
)));
2198 uhci_device_ctrl_start(usbd_xfer_handle xfer
)
2200 uhci_softc_t
*sc
= xfer
->pipe
->device
->bus
->hci_private
;
2204 return (USBD_IOERROR
);
2207 if (!(xfer
->rqflags
& URQ_REQUEST
))
2208 panic("uhci_device_ctrl_transfer: not a request");
2211 err
= uhci_device_request(xfer
);
2215 if (sc
->sc_bus
.use_polling
)
2216 uhci_waitintr(sc
, xfer
);
2217 return (USBD_IN_PROGRESS
);
2221 uhci_device_intr_transfer(usbd_xfer_handle xfer
)
2225 /* Insert last in queue. */
2226 err
= usb_insert_transfer(xfer
);
2231 * Pipe isn't running (otherwise err would be USBD_INPROG),
2232 * so start it first.
2234 return (uhci_device_intr_start(SIMPLEQ_FIRST(&xfer
->pipe
->queue
)));
2238 uhci_device_intr_start(usbd_xfer_handle xfer
)
2240 struct uhci_pipe
*upipe
= (struct uhci_pipe
*)xfer
->pipe
;
2241 usbd_device_handle dev
= upipe
->pipe
.device
;
2242 uhci_softc_t
*sc
= dev
->bus
->hci_private
;
2243 uhci_intr_info_t
*ii
= &UXFER(xfer
)->iinfo
;
2244 uhci_soft_td_t
*data
, *dataend
;
2245 uhci_soft_qh_t
*sqh
;
2251 return (USBD_IOERROR
);
2253 DPRINTFN(3,("uhci_device_intr_transfer: xfer=%p len=%d flags=%d\n",
2254 xfer
, xfer
->length
, xfer
->flags
));
2257 if (xfer
->rqflags
& URQ_REQUEST
)
2258 panic("uhci_device_intr_transfer: a request");
2261 endpt
= upipe
->pipe
.endpoint
->edesc
->bEndpointAddress
;
2262 isread
= UE_GET_DIR(endpt
) == UE_DIR_IN
;
2264 upipe
->u
.intr
.isread
= isread
;
2266 err
= uhci_alloc_std_chain(upipe
, sc
, xfer
->length
, isread
,
2267 xfer
->flags
, &xfer
->dmabuf
, &data
,
2271 dataend
->td
.td_status
|= htole32(UHCI_TD_IOC
);
2272 usb_syncmem(&dataend
->dma
,
2273 dataend
->offs
+ offsetof(uhci_td_t
, td_status
),
2274 sizeof(dataend
->td
.td_status
),
2275 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
2278 if (uhcidebug
> 10) {
2279 DPRINTF(("uhci_device_intr_transfer: data(1)\n"));
2280 uhci_dump_tds(data
);
2281 uhci_dump_qh(upipe
->u
.intr
.qhs
[0]);
2286 /* Set up interrupt info. */
2288 ii
->stdstart
= data
;
2289 ii
->stdend
= dataend
;
2292 printf("uhci_device_intr_transfer: not done, ii=%p\n", ii
);
2297 DPRINTFN(10,("uhci_device_intr_transfer: qhs[0]=%p\n",
2298 upipe
->u
.intr
.qhs
[0]));
2299 for (i
= 0; i
< upipe
->u
.intr
.npoll
; i
++) {
2300 sqh
= upipe
->u
.intr
.qhs
[i
];
2302 sqh
->qh
.qh_elink
= htole32(data
->physaddr
| UHCI_PTR_TD
);
2303 usb_syncmem(&sqh
->dma
,
2304 sqh
->offs
+ offsetof(uhci_qh_t
, qh_elink
),
2305 sizeof(sqh
->qh
.qh_elink
),
2306 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
2308 uhci_add_intr_info(sc
, ii
);
2309 xfer
->status
= USBD_IN_PROGRESS
;
2313 if (uhcidebug
> 10) {
2314 DPRINTF(("uhci_device_intr_transfer: data(2)\n"));
2315 uhci_dump_tds(data
);
2316 uhci_dump_qh(upipe
->u
.intr
.qhs
[0]);
2320 return (USBD_IN_PROGRESS
);
2323 /* Abort a device control request. */
2325 uhci_device_ctrl_abort(usbd_xfer_handle xfer
)
2327 DPRINTF(("uhci_device_ctrl_abort:\n"));
2328 uhci_abort_xfer(xfer
, USBD_CANCELLED
);
2331 /* Close a device control pipe. */
2333 uhci_device_ctrl_close(usbd_pipe_handle pipe
)
2337 /* Abort a device interrupt request. */
2339 uhci_device_intr_abort(usbd_xfer_handle xfer
)
2341 DPRINTFN(1,("uhci_device_intr_abort: xfer=%p\n", xfer
));
2342 if (xfer
->pipe
->intrxfer
== xfer
) {
2343 DPRINTFN(1,("uhci_device_intr_abort: remove\n"));
2344 xfer
->pipe
->intrxfer
= NULL
;
2346 uhci_abort_xfer(xfer
, USBD_CANCELLED
);
2349 /* Close a device interrupt pipe. */
2351 uhci_device_intr_close(usbd_pipe_handle pipe
)
2353 struct uhci_pipe
*upipe
= (struct uhci_pipe
*)pipe
;
2354 uhci_softc_t
*sc
= pipe
->device
->bus
->hci_private
;
2358 /* Unlink descriptors from controller data structures. */
2359 npoll
= upipe
->u
.intr
.npoll
;
2361 for (i
= 0; i
< npoll
; i
++)
2362 uhci_remove_intr(sc
, upipe
->u
.intr
.qhs
[i
]);
2366 * We now have to wait for any activity on the physical
2367 * descriptors to stop.
2369 usb_delay_ms(&sc
->sc_bus
, 2);
2371 for(i
= 0; i
< npoll
; i
++)
2372 uhci_free_sqh(sc
, upipe
->u
.intr
.qhs
[i
]);
2373 free(upipe
->u
.intr
.qhs
, M_USBHC
);
2375 /* XXX free other resources */
2379 uhci_device_request(usbd_xfer_handle xfer
)
2381 struct uhci_pipe
*upipe
= (struct uhci_pipe
*)xfer
->pipe
;
2382 usb_device_request_t
*req
= &xfer
->request
;
2383 usbd_device_handle dev
= upipe
->pipe
.device
;
2384 uhci_softc_t
*sc
= dev
->bus
->hci_private
;
2385 int addr
= dev
->address
;
2386 int endpt
= upipe
->pipe
.endpoint
->edesc
->bEndpointAddress
;
2387 uhci_intr_info_t
*ii
= &UXFER(xfer
)->iinfo
;
2388 uhci_soft_td_t
*setup
, *data
, *stat
, *next
, *dataend
;
2389 uhci_soft_qh_t
*sqh
;
2396 DPRINTFN(3,("uhci_device_control type=0x%02x, request=0x%02x, "
2397 "wValue=0x%04x, wIndex=0x%04x len=%d, addr=%d, endpt=%d\n",
2398 req
->bmRequestType
, req
->bRequest
, UGETW(req
->wValue
),
2399 UGETW(req
->wIndex
), UGETW(req
->wLength
),
2402 ls
= dev
->speed
== USB_SPEED_LOW
? UHCI_TD_LS
: 0;
2403 isread
= req
->bmRequestType
& UT_READ
;
2404 len
= UGETW(req
->wLength
);
2406 setup
= upipe
->u
.ctl
.setup
;
2407 stat
= upipe
->u
.ctl
.stat
;
2408 sqh
= upipe
->u
.ctl
.sqh
;
2410 /* Set up data transaction */
2412 upipe
->nexttoggle
= 1;
2413 err
= uhci_alloc_std_chain(upipe
, sc
, len
, isread
, xfer
->flags
,
2414 &xfer
->dmabuf
, &data
, &dataend
);
2418 dataend
->link
.std
= stat
;
2419 dataend
->td
.td_link
= htole32(stat
->physaddr
| UHCI_PTR_VF
| UHCI_PTR_TD
);
2420 usb_syncmem(&dataend
->dma
,
2421 dataend
->offs
+ offsetof(uhci_td_t
, td_link
),
2422 sizeof(dataend
->td
.td_link
),
2423 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
2427 upipe
->u
.ctl
.length
= len
;
2429 memcpy(KERNADDR(&upipe
->u
.ctl
.reqdma
, 0), req
, sizeof *req
);
2430 usb_syncmem(&upipe
->u
.ctl
.reqdma
, 0, sizeof *req
, BUS_DMASYNC_PREWRITE
);
2432 setup
->link
.std
= next
;
2433 setup
->td
.td_link
= htole32(next
->physaddr
| UHCI_PTR_VF
| UHCI_PTR_TD
);
2434 setup
->td
.td_status
= htole32(UHCI_TD_SET_ERRCNT(3) | ls
|
2436 setup
->td
.td_token
= htole32(UHCI_TD_SETUP(sizeof *req
, endpt
, addr
));
2437 setup
->td
.td_buffer
= htole32(DMAADDR(&upipe
->u
.ctl
.reqdma
, 0));
2438 usb_syncmem(&setup
->dma
, setup
->offs
, sizeof(setup
->td
),
2439 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
2441 stat
->link
.std
= NULL
;
2442 stat
->td
.td_link
= htole32(UHCI_PTR_T
);
2443 stat
->td
.td_status
= htole32(UHCI_TD_SET_ERRCNT(3) | ls
|
2444 UHCI_TD_ACTIVE
| UHCI_TD_IOC
);
2446 htole32(isread
? UHCI_TD_OUT(0, endpt
, addr
, 1) :
2447 UHCI_TD_IN (0, endpt
, addr
, 1));
2448 stat
->td
.td_buffer
= htole32(0);
2449 usb_syncmem(&stat
->dma
, stat
->offs
, sizeof(stat
->td
),
2450 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
2453 if (uhcidebug
> 10) {
2454 DPRINTF(("uhci_device_request: before transfer\n"));
2455 uhci_dump_tds(setup
);
2459 /* Set up interrupt info. */
2461 ii
->stdstart
= setup
;
2465 printf("uhci_device_request: not done, ii=%p\n", ii
);
2471 sqh
->qh
.qh_elink
= htole32(setup
->physaddr
| UHCI_PTR_TD
);
2472 /* uhci_add_?s_ctrl() will do usb_syncmem(sqh) */
2475 if (dev
->speed
== USB_SPEED_LOW
)
2476 uhci_add_ls_ctrl(sc
, sqh
);
2478 uhci_add_hs_ctrl(sc
, sqh
);
2479 uhci_add_intr_info(sc
, ii
);
2481 if (uhcidebug
> 12) {
2482 uhci_soft_td_t
*std
;
2483 uhci_soft_qh_t
*xqh
;
2484 uhci_soft_qh_t
*sxqh
;
2486 uhci_physaddr_t link
;
2487 DPRINTF(("uhci_enter_ctl_q: follow from [0]\n"));
2488 for (std
= sc
->sc_vframes
[0].htd
, link
= 0;
2489 (link
& UHCI_PTR_QH
) == 0;
2490 std
= std
->link
.std
) {
2491 link
= le32toh(std
->td
.td_link
);
2494 sxqh
= (uhci_soft_qh_t
*)std
;
2498 xqh
= (maxqh
++ == 5 || xqh
->hlink
== sxqh
||
2499 xqh
->hlink
== xqh
? NULL
: xqh
->hlink
)) {
2502 DPRINTF(("Enqueued QH:\n"));
2504 uhci_dump_tds(sqh
->elink
);
2507 if (xfer
->timeout
&& !sc
->sc_bus
.use_polling
) {
2508 usb_callout(xfer
->timeout_handle
, mstohz(xfer
->timeout
),
2511 xfer
->status
= USBD_IN_PROGRESS
;
2514 return (USBD_NORMAL_COMPLETION
);
2518 uhci_device_isoc_transfer(usbd_xfer_handle xfer
)
2522 DPRINTFN(5,("uhci_device_isoc_transfer: xfer=%p\n", xfer
));
2524 /* Put it on our queue, */
2525 err
= usb_insert_transfer(xfer
);
2527 /* bail out on error, */
2528 if (err
&& err
!= USBD_IN_PROGRESS
)
2531 /* XXX should check inuse here */
2533 /* insert into schedule, */
2534 uhci_device_isoc_enter(xfer
);
2536 /* and start if the pipe wasn't running */
2538 uhci_device_isoc_start(SIMPLEQ_FIRST(&xfer
->pipe
->queue
));
2544 uhci_device_isoc_enter(usbd_xfer_handle xfer
)
2546 struct uhci_pipe
*upipe
= (struct uhci_pipe
*)xfer
->pipe
;
2547 usbd_device_handle dev
= upipe
->pipe
.device
;
2548 uhci_softc_t
*sc
= dev
->bus
->hci_private
;
2549 struct iso
*iso
= &upipe
->u
.iso
;
2550 uhci_soft_td_t
*std
;
2551 u_int32_t buf
, len
, status
, offs
;
2552 int s
, i
, next
, nframes
;
2553 int rd
= UE_GET_DIR(upipe
->pipe
.endpoint
->edesc
->bEndpointAddress
) == UE_DIR_IN
;
2555 DPRINTFN(5,("uhci_device_isoc_enter: used=%d next=%d xfer=%p "
2557 iso
->inuse
, iso
->next
, xfer
, xfer
->nframes
));
2562 if (xfer
->status
== USBD_IN_PROGRESS
) {
2563 /* This request has already been entered into the frame list */
2564 printf("uhci_device_isoc_enter: xfer=%p in frame list\n", xfer
);
2569 if (iso
->inuse
>= UHCI_VFRAMELIST_COUNT
)
2570 printf("uhci_device_isoc_enter: overflow!\n");
2575 /* Not in use yet, schedule it a few frames ahead. */
2576 next
= (UREAD2(sc
, UHCI_FRNUM
) + 3) % UHCI_VFRAMELIST_COUNT
;
2577 DPRINTFN(2,("uhci_device_isoc_enter: start next=%d\n", next
));
2580 xfer
->status
= USBD_IN_PROGRESS
;
2581 UXFER(xfer
)->curframe
= next
;
2583 buf
= DMAADDR(&xfer
->dmabuf
, 0);
2585 status
= UHCI_TD_ZERO_ACTLEN(UHCI_TD_SET_ERRCNT(0) |
2588 nframes
= xfer
->nframes
;
2590 for (i
= 0; i
< nframes
; i
++) {
2591 std
= iso
->stds
[next
];
2592 if (++next
>= UHCI_VFRAMELIST_COUNT
)
2594 len
= xfer
->frlengths
[i
];
2595 std
->td
.td_buffer
= htole32(buf
);
2596 usb_syncmem(&xfer
->dmabuf
, offs
, len
,
2597 rd
? BUS_DMASYNC_PREREAD
: BUS_DMASYNC_PREWRITE
);
2598 if (i
== nframes
- 1)
2599 status
|= UHCI_TD_IOC
;
2600 std
->td
.td_status
= htole32(status
);
2601 std
->td
.td_token
&= htole32(~UHCI_TD_MAXLEN_MASK
);
2602 std
->td
.td_token
|= htole32(UHCI_TD_SET_MAXLEN(len
));
2603 usb_syncmem(&std
->dma
, std
->offs
, sizeof(std
->td
),
2604 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
2606 if (uhcidebug
> 5) {
2607 DPRINTFN(5,("uhci_device_isoc_enter: TD %d\n", i
));
2615 iso
->inuse
+= xfer
->nframes
;
2621 uhci_device_isoc_start(usbd_xfer_handle xfer
)
2623 struct uhci_pipe
*upipe
= (struct uhci_pipe
*)xfer
->pipe
;
2624 uhci_softc_t
*sc
= upipe
->pipe
.device
->bus
->hci_private
;
2625 uhci_intr_info_t
*ii
= &UXFER(xfer
)->iinfo
;
2626 uhci_soft_td_t
*end
;
2629 DPRINTFN(5,("uhci_device_isoc_start: xfer=%p\n", xfer
));
2632 return (USBD_IOERROR
);
2635 if (xfer
->status
!= USBD_IN_PROGRESS
)
2636 printf("uhci_device_isoc_start: not in progress %p\n", xfer
);
2639 /* Find the last TD */
2640 i
= UXFER(xfer
)->curframe
+ xfer
->nframes
;
2641 if (i
>= UHCI_VFRAMELIST_COUNT
)
2642 i
-= UHCI_VFRAMELIST_COUNT
;
2643 end
= upipe
->u
.iso
.stds
[i
];
2647 printf("uhci_device_isoc_start: end == NULL\n");
2648 return (USBD_INVAL
);
2654 /* Set up interrupt info. */
2660 printf("uhci_device_isoc_start: not done, ii=%p\n", ii
);
2663 uhci_add_intr_info(sc
, ii
);
2667 return (USBD_IN_PROGRESS
);
2671 uhci_device_isoc_abort(usbd_xfer_handle xfer
)
2673 struct uhci_pipe
*upipe
= (struct uhci_pipe
*)xfer
->pipe
;
2674 uhci_soft_td_t
**stds
= upipe
->u
.iso
.stds
;
2675 uhci_soft_td_t
*std
;
2676 int i
, n
, s
, nframes
, maxlen
, len
;
2680 /* Transfer is already done. */
2681 if (xfer
->status
!= USBD_NOT_STARTED
&&
2682 xfer
->status
!= USBD_IN_PROGRESS
) {
2687 /* Give xfer the requested abort code. */
2688 xfer
->status
= USBD_CANCELLED
;
2690 /* make hardware ignore it, */
2691 nframes
= xfer
->nframes
;
2692 n
= UXFER(xfer
)->curframe
;
2694 for (i
= 0; i
< nframes
; i
++) {
2696 usb_syncmem(&std
->dma
,
2697 std
->offs
+ offsetof(uhci_td_t
, td_status
),
2698 sizeof(std
->td
.td_status
),
2699 BUS_DMASYNC_POSTWRITE
| BUS_DMASYNC_POSTREAD
);
2700 std
->td
.td_status
&= htole32(~(UHCI_TD_ACTIVE
| UHCI_TD_IOC
));
2701 usb_syncmem(&std
->dma
,
2702 std
->offs
+ offsetof(uhci_td_t
, td_status
),
2703 sizeof(std
->td
.td_status
),
2704 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
2705 usb_syncmem(&std
->dma
,
2706 std
->offs
+ offsetof(uhci_td_t
, td_token
),
2707 sizeof(std
->td
.td_token
),
2708 BUS_DMASYNC_POSTWRITE
);
2709 len
= UHCI_TD_GET_MAXLEN(le32toh(std
->td
.td_token
));
2712 if (++n
>= UHCI_VFRAMELIST_COUNT
)
2716 /* and wait until we are sure the hardware has finished. */
2720 UXFER(xfer
)->iinfo
.isdone
= 1;
2722 /* Run callback and remove from interrupt list. */
2723 usb_transfer_complete(xfer
);
2729 uhci_device_isoc_close(usbd_pipe_handle pipe
)
2731 struct uhci_pipe
*upipe
= (struct uhci_pipe
*)pipe
;
2732 usbd_device_handle dev
= upipe
->pipe
.device
;
2733 uhci_softc_t
*sc
= dev
->bus
->hci_private
;
2734 uhci_soft_td_t
*std
, *vstd
;
2739 * Make sure all TDs are marked as inactive.
2740 * Wait for completion.
2744 iso
= &upipe
->u
.iso
;
2746 for (i
= 0; i
< UHCI_VFRAMELIST_COUNT
; i
++) {
2748 usb_syncmem(&std
->dma
,
2749 std
->offs
+ offsetof(uhci_td_t
, td_status
),
2750 sizeof(std
->td
.td_status
),
2751 BUS_DMASYNC_POSTWRITE
| BUS_DMASYNC_POSTREAD
);
2752 std
->td
.td_status
&= htole32(~UHCI_TD_ACTIVE
);
2753 usb_syncmem(&std
->dma
,
2754 std
->offs
+ offsetof(uhci_td_t
, td_status
),
2755 sizeof(std
->td
.td_status
),
2756 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
2758 usb_delay_ms(&sc
->sc_bus
, 2); /* wait for completion */
2761 for (i
= 0; i
< UHCI_VFRAMELIST_COUNT
; i
++) {
2763 for (vstd
= sc
->sc_vframes
[i
].htd
;
2764 vstd
!= NULL
&& vstd
->link
.std
!= std
;
2765 vstd
= vstd
->link
.std
)
2769 printf("uhci_device_isoc_close: %p not found\n", std
);
2773 vstd
->link
= std
->link
;
2774 usb_syncmem(&std
->dma
,
2775 std
->offs
+ offsetof(uhci_td_t
, td_link
),
2776 sizeof(std
->td
.td_link
),
2777 BUS_DMASYNC_POSTWRITE
);
2778 vstd
->td
.td_link
= std
->td
.td_link
;
2779 usb_syncmem(&vstd
->dma
,
2780 vstd
->offs
+ offsetof(uhci_td_t
, td_link
),
2781 sizeof(vstd
->td
.td_link
),
2782 BUS_DMASYNC_PREWRITE
);
2783 uhci_free_std(sc
, std
);
2787 free(iso
->stds
, M_USBHC
);
2791 uhci_setup_isoc(usbd_pipe_handle pipe
)
2793 struct uhci_pipe
*upipe
= (struct uhci_pipe
*)pipe
;
2794 usbd_device_handle dev
= upipe
->pipe
.device
;
2795 uhci_softc_t
*sc
= dev
->bus
->hci_private
;
2796 int addr
= upipe
->pipe
.device
->address
;
2797 int endpt
= upipe
->pipe
.endpoint
->edesc
->bEndpointAddress
;
2798 int rd
= UE_GET_DIR(endpt
) == UE_DIR_IN
;
2799 uhci_soft_td_t
*std
, *vstd
;
2804 iso
= &upipe
->u
.iso
;
2805 iso
->stds
= malloc(UHCI_VFRAMELIST_COUNT
* sizeof (uhci_soft_td_t
*),
2808 token
= rd
? UHCI_TD_IN (0, endpt
, addr
, 0) :
2809 UHCI_TD_OUT(0, endpt
, addr
, 0);
2811 /* Allocate the TDs and mark as inactive; */
2812 for (i
= 0; i
< UHCI_VFRAMELIST_COUNT
; i
++) {
2813 std
= uhci_alloc_std(sc
);
2816 std
->td
.td_status
= htole32(UHCI_TD_IOS
); /* iso, inactive */
2817 std
->td
.td_token
= htole32(token
);
2818 usb_syncmem(&std
->dma
, std
->offs
, sizeof(std
->td
),
2819 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
2823 /* Insert TDs into schedule. */
2825 for (i
= 0; i
< UHCI_VFRAMELIST_COUNT
; i
++) {
2827 vstd
= sc
->sc_vframes
[i
].htd
;
2828 usb_syncmem(&vstd
->dma
,
2829 vstd
->offs
+ offsetof(uhci_td_t
, td_link
),
2830 sizeof(vstd
->td
.td_link
),
2831 BUS_DMASYNC_POSTWRITE
);
2832 std
->link
= vstd
->link
;
2833 std
->td
.td_link
= vstd
->td
.td_link
;
2834 usb_syncmem(&std
->dma
,
2835 std
->offs
+ offsetof(uhci_td_t
, td_link
),
2836 sizeof(std
->td
.td_link
),
2837 BUS_DMASYNC_PREWRITE
);
2838 vstd
->link
.std
= std
;
2839 vstd
->td
.td_link
= htole32(std
->physaddr
| UHCI_PTR_TD
);
2840 usb_syncmem(&vstd
->dma
,
2841 vstd
->offs
+ offsetof(uhci_td_t
, td_link
),
2842 sizeof(vstd
->td
.td_link
),
2843 BUS_DMASYNC_PREWRITE
);
2850 return (USBD_NORMAL_COMPLETION
);
2854 uhci_free_std(sc
, iso
->stds
[i
]);
2855 free(iso
->stds
, M_USBHC
);
2856 return (USBD_NOMEM
);
2860 uhci_device_isoc_done(usbd_xfer_handle xfer
)
2862 uhci_intr_info_t
*ii
= &UXFER(xfer
)->iinfo
;
2863 struct uhci_pipe
*upipe
= (struct uhci_pipe
*)xfer
->pipe
;
2865 int rd
= UE_GET_DIR(upipe
->pipe
.endpoint
->edesc
->bEndpointAddress
) == UE_DIR_IN
;
2868 DPRINTFN(4, ("uhci_isoc_done: length=%d, busy_free=0x%08x\n",
2869 xfer
->actlen
, xfer
->busy_free
));
2871 if (ii
->xfer
!= xfer
)
2872 /* Not on interrupt list, ignore it. */
2875 if (!uhci_active_intr_info(ii
))
2879 if (ii
->stdend
== NULL
) {
2880 printf("uhci_device_isoc_done: xfer=%p stdend==NULL\n", xfer
);
2888 /* Turn off the interrupt since it is active even if the TD is not. */
2889 usb_syncmem(&ii
->stdend
->dma
,
2890 ii
->stdend
->offs
+ offsetof(uhci_td_t
, td_status
),
2891 sizeof(ii
->stdend
->td
.td_status
),
2892 BUS_DMASYNC_POSTWRITE
| BUS_DMASYNC_POSTREAD
);
2893 ii
->stdend
->td
.td_status
&= htole32(~UHCI_TD_IOC
);
2894 usb_syncmem(&ii
->stdend
->dma
,
2895 ii
->stdend
->offs
+ offsetof(uhci_td_t
, td_status
),
2896 sizeof(ii
->stdend
->td
.td_status
),
2897 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
2899 uhci_del_intr_info(ii
); /* remove from active list */
2902 for (i
= 0; i
< xfer
->nframes
; i
++) {
2903 usb_syncmem(&xfer
->dmabuf
, offs
, xfer
->frlengths
[i
],
2904 rd
? BUS_DMASYNC_POSTREAD
: BUS_DMASYNC_POSTWRITE
);
2905 offs
+= xfer
->frlengths
[i
];
2910 uhci_device_intr_done(usbd_xfer_handle xfer
)
2912 uhci_intr_info_t
*ii
= &UXFER(xfer
)->iinfo
;
2913 uhci_softc_t
*sc
= ii
->sc
;
2914 struct uhci_pipe
*upipe
= (struct uhci_pipe
*)xfer
->pipe
;
2915 uhci_soft_qh_t
*sqh
;
2916 int i
, npoll
, isread
;
2918 DPRINTFN(5, ("uhci_device_intr_done: length=%d\n", xfer
->actlen
));
2920 npoll
= upipe
->u
.intr
.npoll
;
2921 for(i
= 0; i
< npoll
; i
++) {
2922 sqh
= upipe
->u
.intr
.qhs
[i
];
2924 sqh
->qh
.qh_elink
= htole32(UHCI_PTR_T
);
2925 usb_syncmem(&sqh
->dma
,
2926 sqh
->offs
+ offsetof(uhci_qh_t
, qh_elink
),
2927 sizeof(sqh
->qh
.qh_elink
),
2928 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
2930 uhci_free_std_chain(sc
, ii
->stdstart
, NULL
);
2932 isread
= UE_GET_DIR(upipe
->pipe
.endpoint
->edesc
->bEndpointAddress
) == UE_DIR_IN
;
2933 usb_syncmem(&xfer
->dmabuf
, 0, xfer
->length
,
2934 isread
? BUS_DMASYNC_POSTREAD
: BUS_DMASYNC_POSTWRITE
);
2937 if (xfer
->pipe
->repeat
) {
2938 uhci_soft_td_t
*data
, *dataend
;
2940 DPRINTFN(5,("uhci_device_intr_done: requeing\n"));
2942 /* This alloc cannot fail since we freed the chain above. */
2943 uhci_alloc_std_chain(upipe
, sc
, xfer
->length
,
2944 upipe
->u
.intr
.isread
, xfer
->flags
,
2945 &xfer
->dmabuf
, &data
, &dataend
);
2946 dataend
->td
.td_status
|= htole32(UHCI_TD_IOC
);
2947 usb_syncmem(&dataend
->dma
,
2948 dataend
->offs
+ offsetof(uhci_td_t
, td_status
),
2949 sizeof(dataend
->td
.td_status
),
2950 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
2953 if (uhcidebug
> 10) {
2954 DPRINTF(("uhci_device_intr_done: data(1)\n"));
2955 uhci_dump_tds(data
);
2956 uhci_dump_qh(upipe
->u
.intr
.qhs
[0]);
2960 ii
->stdstart
= data
;
2961 ii
->stdend
= dataend
;
2964 printf("uhci_device_intr_done: not done, ii=%p\n", ii
);
2968 for (i
= 0; i
< npoll
; i
++) {
2969 sqh
= upipe
->u
.intr
.qhs
[i
];
2971 sqh
->qh
.qh_elink
= htole32(data
->physaddr
| UHCI_PTR_TD
);
2972 usb_syncmem(&sqh
->dma
,
2973 sqh
->offs
+ offsetof(uhci_qh_t
, qh_elink
),
2974 sizeof(sqh
->qh
.qh_elink
),
2975 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
2977 xfer
->status
= USBD_IN_PROGRESS
;
2978 /* The ii is already on the examined list, just leave it. */
2980 DPRINTFN(5,("uhci_device_intr_done: removing\n"));
2981 if (uhci_active_intr_info(ii
))
2982 uhci_del_intr_info(ii
);
2986 /* Deallocate request data structures */
2988 uhci_device_ctrl_done(usbd_xfer_handle xfer
)
2990 uhci_intr_info_t
*ii
= &UXFER(xfer
)->iinfo
;
2991 uhci_softc_t
*sc
= ii
->sc
;
2992 struct uhci_pipe
*upipe
= (struct uhci_pipe
*)xfer
->pipe
;
2993 int len
= UGETW(xfer
->request
.wLength
);
2994 int isread
= (xfer
->request
.bmRequestType
& UT_READ
);
2997 if (!(xfer
->rqflags
& URQ_REQUEST
))
2998 panic("uhci_device_ctrl_done: not a request");
3001 if (!uhci_active_intr_info(ii
))
3004 uhci_del_intr_info(ii
); /* remove from active list */
3006 if (upipe
->pipe
.device
->speed
== USB_SPEED_LOW
)
3007 uhci_remove_ls_ctrl(sc
, upipe
->u
.ctl
.sqh
);
3009 uhci_remove_hs_ctrl(sc
, upipe
->u
.ctl
.sqh
);
3011 if (upipe
->u
.ctl
.length
!= 0)
3012 uhci_free_std_chain(sc
, ii
->stdstart
->link
.std
, ii
->stdend
);
3015 usb_syncmem(&xfer
->dmabuf
, 0, len
,
3016 isread
? BUS_DMASYNC_POSTREAD
: BUS_DMASYNC_POSTWRITE
);
3018 usb_syncmem(&upipe
->u
.ctl
.reqdma
, 0,
3019 sizeof(usb_device_request_t
), BUS_DMASYNC_POSTWRITE
);
3021 DPRINTFN(5, ("uhci_device_ctrl_done: length=%d\n", xfer
->actlen
));
3024 /* Deallocate request data structures */
3026 uhci_device_bulk_done(usbd_xfer_handle xfer
)
3028 uhci_intr_info_t
*ii
= &UXFER(xfer
)->iinfo
;
3029 uhci_softc_t
*sc
= ii
->sc
;
3030 struct uhci_pipe
*upipe
= (struct uhci_pipe
*)xfer
->pipe
;
3032 DPRINTFN(5,("uhci_device_bulk_done: xfer=%p ii=%p sc=%p upipe=%p\n",
3033 xfer
, ii
, sc
, upipe
));
3035 if (!uhci_active_intr_info(ii
))
3038 uhci_del_intr_info(ii
); /* remove from active list */
3040 uhci_remove_bulk(sc
, upipe
->u
.bulk
.sqh
);
3042 uhci_free_std_chain(sc
, ii
->stdstart
, NULL
);
3044 DPRINTFN(5, ("uhci_device_bulk_done: length=%d\n", xfer
->actlen
));
3047 /* Add interrupt QH, called with vflock. */
3049 uhci_add_intr(uhci_softc_t
*sc
, uhci_soft_qh_t
*sqh
)
3051 struct uhci_vframe
*vf
= &sc
->sc_vframes
[sqh
->pos
];
3052 uhci_soft_qh_t
*eqh
;
3054 DPRINTFN(4, ("uhci_add_intr: n=%d sqh=%p\n", sqh
->pos
, sqh
));
3057 usb_syncmem(&eqh
->dma
, eqh
->offs
+ offsetof(uhci_qh_t
, qh_hlink
),
3058 sizeof(eqh
->qh
.qh_hlink
),
3059 BUS_DMASYNC_POSTWRITE
);
3060 sqh
->hlink
= eqh
->hlink
;
3061 sqh
->qh
.qh_hlink
= eqh
->qh
.qh_hlink
;
3062 usb_syncmem(&sqh
->dma
, sqh
->offs
+ offsetof(uhci_qh_t
, qh_hlink
),
3063 sizeof(sqh
->qh
.qh_hlink
),
3064 BUS_DMASYNC_PREWRITE
);
3066 eqh
->qh
.qh_hlink
= htole32(sqh
->physaddr
| UHCI_PTR_QH
);
3067 usb_syncmem(&eqh
->dma
, eqh
->offs
+ offsetof(uhci_qh_t
, qh_hlink
),
3068 sizeof(eqh
->qh
.qh_hlink
),
3069 BUS_DMASYNC_PREWRITE
);
3074 /* Remove interrupt QH. */
3076 uhci_remove_intr(uhci_softc_t
*sc
, uhci_soft_qh_t
*sqh
)
3078 struct uhci_vframe
*vf
= &sc
->sc_vframes
[sqh
->pos
];
3079 uhci_soft_qh_t
*pqh
;
3081 DPRINTFN(4, ("uhci_remove_intr: n=%d sqh=%p\n", sqh
->pos
, sqh
));
3083 /* See comment in uhci_remove_ctrl() */
3085 usb_syncmem(&sqh
->dma
, sqh
->offs
+ offsetof(uhci_qh_t
, qh_elink
),
3086 sizeof(sqh
->qh
.qh_elink
),
3087 BUS_DMASYNC_POSTWRITE
| BUS_DMASYNC_POSTREAD
);
3088 if (!(sqh
->qh
.qh_elink
& htole32(UHCI_PTR_T
))) {
3089 sqh
->qh
.qh_elink
= htole32(UHCI_PTR_T
);
3090 usb_syncmem(&sqh
->dma
,
3091 sqh
->offs
+ offsetof(uhci_qh_t
, qh_elink
),
3092 sizeof(sqh
->qh
.qh_elink
),
3093 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
3094 delay(UHCI_QH_REMOVE_DELAY
);
3097 pqh
= uhci_find_prev_qh(vf
->hqh
, sqh
);
3098 usb_syncmem(&sqh
->dma
, sqh
->offs
+ offsetof(uhci_qh_t
, qh_hlink
),
3099 sizeof(sqh
->qh
.qh_hlink
),
3100 BUS_DMASYNC_POSTWRITE
| BUS_DMASYNC_POSTREAD
);
3101 pqh
->hlink
= sqh
->hlink
;
3102 pqh
->qh
.qh_hlink
= sqh
->qh
.qh_hlink
;
3103 usb_syncmem(&pqh
->dma
, pqh
->offs
+ offsetof(uhci_qh_t
, qh_hlink
),
3104 sizeof(pqh
->qh
.qh_hlink
),
3105 BUS_DMASYNC_PREWRITE
);
3106 delay(UHCI_QH_REMOVE_DELAY
);
3113 uhci_device_setintr(uhci_softc_t
*sc
, struct uhci_pipe
*upipe
, int ival
)
3115 uhci_soft_qh_t
*sqh
;
3117 u_int bestbw
, bw
, bestoffs
, offs
;
3119 DPRINTFN(2, ("uhci_device_setintr: pipe=%p\n", upipe
));
3121 printf("uhci_device_setintr: 0 interval\n");
3122 return (USBD_INVAL
);
3125 if (ival
> UHCI_VFRAMELIST_COUNT
)
3126 ival
= UHCI_VFRAMELIST_COUNT
;
3127 npoll
= (UHCI_VFRAMELIST_COUNT
+ ival
- 1) / ival
;
3128 DPRINTFN(2, ("uhci_device_setintr: ival=%d npoll=%d\n", ival
, npoll
));
3130 upipe
->u
.intr
.npoll
= npoll
;
3132 malloc(npoll
* sizeof(uhci_soft_qh_t
*), M_USBHC
, M_WAITOK
);
3135 * Figure out which offset in the schedule that has most
3136 * bandwidth left over.
3138 #define MOD(i) ((i) & (UHCI_VFRAMELIST_COUNT-1))
3139 for (bestoffs
= offs
= 0, bestbw
= ~0; offs
< ival
; offs
++) {
3140 for (bw
= i
= 0; i
< npoll
; i
++)
3141 bw
+= sc
->sc_vframes
[MOD(i
* ival
+ offs
)].bandwidth
;
3147 DPRINTFN(1, ("uhci_device_setintr: bw=%d offs=%d\n", bestbw
, bestoffs
));
3149 for(i
= 0; i
< npoll
; i
++) {
3150 upipe
->u
.intr
.qhs
[i
] = sqh
= uhci_alloc_sqh(sc
);
3152 sqh
->qh
.qh_elink
= htole32(UHCI_PTR_T
);
3153 usb_syncmem(&sqh
->dma
,
3154 sqh
->offs
+ offsetof(uhci_qh_t
, qh_elink
),
3155 sizeof(sqh
->qh
.qh_elink
),
3156 BUS_DMASYNC_PREWRITE
| BUS_DMASYNC_PREREAD
);
3157 sqh
->pos
= MOD(i
* ival
+ bestoffs
);
3162 /* Enter QHs into the controller data structures. */
3163 for(i
= 0; i
< npoll
; i
++)
3164 uhci_add_intr(sc
, upipe
->u
.intr
.qhs
[i
]);
3167 DPRINTFN(5, ("uhci_device_setintr: returns %p\n", upipe
));
3168 return (USBD_NORMAL_COMPLETION
);
3171 /* Open a new pipe. */
3173 uhci_open(usbd_pipe_handle pipe
)
3175 uhci_softc_t
*sc
= pipe
->device
->bus
->hci_private
;
3176 struct uhci_pipe
*upipe
= (struct uhci_pipe
*)pipe
;
3177 usb_endpoint_descriptor_t
*ed
= pipe
->endpoint
->edesc
;
3181 DPRINTFN(1, ("uhci_open: pipe=%p, addr=%d, endpt=%d (%d)\n",
3182 pipe
, pipe
->device
->address
,
3183 ed
->bEndpointAddress
, sc
->sc_addr
));
3185 upipe
->aborting
= 0;
3186 upipe
->nexttoggle
= 0;
3188 if (pipe
->device
->address
== sc
->sc_addr
) {
3189 switch (ed
->bEndpointAddress
) {
3190 case USB_CONTROL_ENDPOINT
:
3191 pipe
->methods
= &uhci_root_ctrl_methods
;
3193 case UE_DIR_IN
| UHCI_INTR_ENDPT
:
3194 pipe
->methods
= &uhci_root_intr_methods
;
3197 return (USBD_INVAL
);
3200 switch (ed
->bmAttributes
& UE_XFERTYPE
) {
3202 pipe
->methods
= &uhci_device_ctrl_methods
;
3203 upipe
->u
.ctl
.sqh
= uhci_alloc_sqh(sc
);
3204 if (upipe
->u
.ctl
.sqh
== NULL
)
3206 upipe
->u
.ctl
.setup
= uhci_alloc_std(sc
);
3207 if (upipe
->u
.ctl
.setup
== NULL
) {
3208 uhci_free_sqh(sc
, upipe
->u
.ctl
.sqh
);
3211 upipe
->u
.ctl
.stat
= uhci_alloc_std(sc
);
3212 if (upipe
->u
.ctl
.stat
== NULL
) {
3213 uhci_free_sqh(sc
, upipe
->u
.ctl
.sqh
);
3214 uhci_free_std(sc
, upipe
->u
.ctl
.setup
);
3217 err
= usb_allocmem(&sc
->sc_bus
,
3218 sizeof(usb_device_request_t
),
3219 0, &upipe
->u
.ctl
.reqdma
);
3221 uhci_free_sqh(sc
, upipe
->u
.ctl
.sqh
);
3222 uhci_free_std(sc
, upipe
->u
.ctl
.setup
);
3223 uhci_free_std(sc
, upipe
->u
.ctl
.stat
);
3228 pipe
->methods
= &uhci_device_intr_methods
;
3229 ival
= pipe
->interval
;
3230 if (ival
== USBD_DEFAULT_INTERVAL
)
3231 ival
= ed
->bInterval
;
3232 return (uhci_device_setintr(sc
, upipe
, ival
));
3233 case UE_ISOCHRONOUS
:
3234 pipe
->methods
= &uhci_device_isoc_methods
;
3235 return (uhci_setup_isoc(pipe
));
3237 pipe
->methods
= &uhci_device_bulk_methods
;
3238 upipe
->u
.bulk
.sqh
= uhci_alloc_sqh(sc
);
3239 if (upipe
->u
.bulk
.sqh
== NULL
)
3244 return (USBD_NORMAL_COMPLETION
);
3247 return (USBD_NOMEM
);
3251 * Data structures and routines to emulate the root hub.
3253 usb_device_descriptor_t uhci_devd
= {
3254 USB_DEVICE_DESCRIPTOR_SIZE
,
3255 UDESC_DEVICE
, /* type */
3256 {0x00, 0x01}, /* USB version */
3257 UDCLASS_HUB
, /* class */
3258 UDSUBCLASS_HUB
, /* subclass */
3259 UDPROTO_FSHUB
, /* protocol */
3260 64, /* max packet */
3261 {0},{0},{0x00,0x01}, /* device id */
3262 1,2,0, /* string indicies */
3263 1 /* # of configurations */
3266 const usb_config_descriptor_t uhci_confd
= {
3267 USB_CONFIG_DESCRIPTOR_SIZE
,
3269 {USB_CONFIG_DESCRIPTOR_SIZE
+
3270 USB_INTERFACE_DESCRIPTOR_SIZE
+
3271 USB_ENDPOINT_DESCRIPTOR_SIZE
},
3275 UC_ATTR_MBO
| UC_SELF_POWERED
,
3279 const usb_interface_descriptor_t uhci_ifcd
= {
3280 USB_INTERFACE_DESCRIPTOR_SIZE
,
3291 const usb_endpoint_descriptor_t uhci_endpd
= {
3292 USB_ENDPOINT_DESCRIPTOR_SIZE
,
3294 UE_DIR_IN
| UHCI_INTR_ENDPT
,
3300 const usb_hub_descriptor_t uhci_hubd_piix
= {
3301 USB_HUB_DESCRIPTOR_SIZE
,
3304 { UHD_PWR_NO_SWITCH
| UHD_OC_INDIVIDUAL
, 0 },
3305 50, /* power on to power good */
3307 { 0x00 }, /* both ports are removable */
3312 * The USB hub protocol requires that SET_FEATURE(PORT_RESET) also
3313 * enables the port, and also states that SET_FEATURE(PORT_ENABLE)
3314 * should not be used by the USB subsystem. As we cannot issue a
3315 * SET_FEATURE(PORT_ENABLE) externally, we must ensure that the port
3316 * will be enabled as part of the reset.
3318 * On the VT83C572, the port cannot be successfully enabled until the
3319 * outstanding "port enable change" and "connection status change"
3320 * events have been reset.
3323 uhci_portreset(uhci_softc_t
*sc
, int index
)
3328 port
= UHCI_PORTSC1
;
3329 else if (index
== 2)
3330 port
= UHCI_PORTSC2
;
3332 return (USBD_IOERROR
);
3334 x
= URWMASK(UREAD2(sc
, port
));
3335 UWRITE2(sc
, port
, x
| UHCI_PORTSC_PR
);
3337 usb_delay_ms(&sc
->sc_bus
, USB_PORT_ROOT_RESET_DELAY
);
3339 DPRINTFN(3,("uhci port %d reset, status0 = 0x%04x\n",
3340 index
, UREAD2(sc
, port
)));
3342 x
= URWMASK(UREAD2(sc
, port
));
3343 UWRITE2(sc
, port
, x
& ~(UHCI_PORTSC_PR
| UHCI_PORTSC_SUSP
));
3347 DPRINTFN(3,("uhci port %d reset, status1 = 0x%04x\n",
3348 index
, UREAD2(sc
, port
)));
3350 x
= URWMASK(UREAD2(sc
, port
));
3351 UWRITE2(sc
, port
, x
| UHCI_PORTSC_PE
);
3353 for (lim
= 10; --lim
> 0;) {
3354 usb_delay_ms(&sc
->sc_bus
, USB_PORT_RESET_DELAY
);
3356 x
= UREAD2(sc
, port
);
3358 DPRINTFN(3,("uhci port %d iteration %u, status = 0x%04x\n",
3361 if (!(x
& UHCI_PORTSC_CCS
)) {
3363 * No device is connected (or was disconnected
3364 * during reset). Consider the port reset.
3365 * The delay must be long enough to ensure on
3366 * the initial iteration that the device
3367 * connection will have been registered. 50ms
3368 * appears to be sufficient, but 20ms is not.
3370 DPRINTFN(3,("uhci port %d loop %u, device detached\n",
3375 if (x
& (UHCI_PORTSC_POEDC
| UHCI_PORTSC_CSC
)) {
3377 * Port enabled changed and/or connection
3378 * status changed were set. Reset either or
3379 * both raised flags (by writing a 1 to that
3380 * bit), and wait again for state to settle.
3382 UWRITE2(sc
, port
, URWMASK(x
) |
3383 (x
& (UHCI_PORTSC_POEDC
| UHCI_PORTSC_CSC
)));
3387 if (x
& UHCI_PORTSC_PE
)
3388 /* Port is enabled */
3391 UWRITE2(sc
, port
, URWMASK(x
) | UHCI_PORTSC_PE
);
3394 DPRINTFN(3,("uhci port %d reset, status2 = 0x%04x\n",
3395 index
, UREAD2(sc
, port
)));
3398 DPRINTFN(1,("uhci port %d reset timed out\n", index
));
3399 return (USBD_TIMEOUT
);
3403 return (USBD_NORMAL_COMPLETION
);
3407 * Simulate a hardware hub by handling all the necessary requests.
3410 uhci_root_ctrl_transfer(usbd_xfer_handle xfer
)
3414 /* Insert last in queue. */
3415 err
= usb_insert_transfer(xfer
);
3420 * Pipe isn't running (otherwise err would be USBD_INPROG),
3421 * so start it first.
3423 return (uhci_root_ctrl_start(SIMPLEQ_FIRST(&xfer
->pipe
->queue
)));
3427 uhci_root_ctrl_start(usbd_xfer_handle xfer
)
3429 uhci_softc_t
*sc
= xfer
->pipe
->device
->bus
->hci_private
;
3430 usb_device_request_t
*req
;
3433 int s
, len
, value
, index
, status
, change
, l
, totlen
= 0;
3434 usb_port_status_t ps
;
3438 return (USBD_IOERROR
);
3441 if (!(xfer
->rqflags
& URQ_REQUEST
))
3442 panic("uhci_root_ctrl_transfer: not a request");
3444 req
= &xfer
->request
;
3446 DPRINTFN(2,("uhci_root_ctrl_control type=0x%02x request=%02x\n",
3447 req
->bmRequestType
, req
->bRequest
));
3449 len
= UGETW(req
->wLength
);
3450 value
= UGETW(req
->wValue
);
3451 index
= UGETW(req
->wIndex
);
3454 buf
= KERNADDR(&xfer
->dmabuf
, 0);
3456 #define C(x,y) ((x) | ((y) << 8))
3457 switch(C(req
->bRequest
, req
->bmRequestType
)) {
3458 case C(UR_CLEAR_FEATURE
, UT_WRITE_DEVICE
):
3459 case C(UR_CLEAR_FEATURE
, UT_WRITE_INTERFACE
):
3460 case C(UR_CLEAR_FEATURE
, UT_WRITE_ENDPOINT
):
3462 * DEVICE_REMOTE_WAKEUP and ENDPOINT_HALT are no-ops
3463 * for the integrated root hub.
3466 case C(UR_GET_CONFIG
, UT_READ_DEVICE
):
3468 *(u_int8_t
*)buf
= sc
->sc_conf
;
3472 case C(UR_GET_DESCRIPTOR
, UT_READ_DEVICE
):
3473 DPRINTFN(2,("uhci_root_ctrl_control wValue=0x%04x\n", value
));
3476 switch(value
>> 8) {
3478 if ((value
& 0xff) != 0) {
3482 totlen
= l
= min(len
, USB_DEVICE_DESCRIPTOR_SIZE
);
3483 USETW(uhci_devd
.idVendor
, sc
->sc_id_vendor
);
3484 memcpy(buf
, &uhci_devd
, l
);
3487 if ((value
& 0xff) != 0) {
3491 totlen
= l
= min(len
, USB_CONFIG_DESCRIPTOR_SIZE
);
3492 memcpy(buf
, &uhci_confd
, l
);
3493 buf
= (char *)buf
+ l
;
3495 l
= min(len
, USB_INTERFACE_DESCRIPTOR_SIZE
);
3497 memcpy(buf
, &uhci_ifcd
, l
);
3498 buf
= (char *)buf
+ l
;
3500 l
= min(len
, USB_ENDPOINT_DESCRIPTOR_SIZE
);
3502 memcpy(buf
, &uhci_endpd
, l
);
3505 #define sd ((usb_string_descriptor_t *)buf)
3506 switch (value
& 0xff) {
3507 case 0: /* Language table */
3508 totlen
= usb_makelangtbl(sd
, len
);
3510 case 1: /* Vendor */
3511 totlen
= usb_makestrdesc(sd
, len
,
3514 case 2: /* Product */
3515 totlen
= usb_makestrdesc(sd
, len
,
3526 case C(UR_GET_INTERFACE
, UT_READ_INTERFACE
):
3528 *(u_int8_t
*)buf
= 0;
3532 case C(UR_GET_STATUS
, UT_READ_DEVICE
):
3534 USETW(((usb_status_t
*)buf
)->wStatus
,UDS_SELF_POWERED
);
3538 case C(UR_GET_STATUS
, UT_READ_INTERFACE
):
3539 case C(UR_GET_STATUS
, UT_READ_ENDPOINT
):
3541 USETW(((usb_status_t
*)buf
)->wStatus
, 0);
3545 case C(UR_SET_ADDRESS
, UT_WRITE_DEVICE
):
3546 if (value
>= USB_MAX_DEVICES
) {
3550 sc
->sc_addr
= value
;
3552 case C(UR_SET_CONFIG
, UT_WRITE_DEVICE
):
3553 if (value
!= 0 && value
!= 1) {
3557 sc
->sc_conf
= value
;
3559 case C(UR_SET_DESCRIPTOR
, UT_WRITE_DEVICE
):
3561 case C(UR_SET_FEATURE
, UT_WRITE_DEVICE
):
3562 case C(UR_SET_FEATURE
, UT_WRITE_INTERFACE
):
3563 case C(UR_SET_FEATURE
, UT_WRITE_ENDPOINT
):
3566 case C(UR_SET_INTERFACE
, UT_WRITE_INTERFACE
):
3568 case C(UR_SYNCH_FRAME
, UT_WRITE_ENDPOINT
):
3571 case C(UR_CLEAR_FEATURE
, UT_WRITE_CLASS_DEVICE
):
3573 case C(UR_CLEAR_FEATURE
, UT_WRITE_CLASS_OTHER
):
3574 DPRINTFN(3, ("uhci_root_ctrl_control: UR_CLEAR_PORT_FEATURE "
3575 "port=%d feature=%d\n",
3578 port
= UHCI_PORTSC1
;
3579 else if (index
== 2)
3580 port
= UHCI_PORTSC2
;
3586 case UHF_PORT_ENABLE
:
3587 x
= URWMASK(UREAD2(sc
, port
));
3588 UWRITE2(sc
, port
, x
& ~UHCI_PORTSC_PE
);
3590 case UHF_PORT_SUSPEND
:
3591 x
= URWMASK(UREAD2(sc
, port
));
3592 if (!(x
& UHCI_PORTSC_SUSP
)) /* not suspended */
3594 UWRITE2(sc
, port
, x
| UHCI_PORTSC_RD
);
3595 /* see USB2 spec ch. 7.1.7.7 */
3596 usb_delay_ms(&sc
->sc_bus
, 20);
3597 UWRITE2(sc
, port
, x
& ~UHCI_PORTSC_SUSP
);
3598 /* 10ms resume delay must be provided by caller */
3600 case UHF_PORT_RESET
:
3601 x
= URWMASK(UREAD2(sc
, port
));
3602 UWRITE2(sc
, port
, x
& ~UHCI_PORTSC_PR
);
3604 case UHF_C_PORT_CONNECTION
:
3605 x
= URWMASK(UREAD2(sc
, port
));
3606 UWRITE2(sc
, port
, x
| UHCI_PORTSC_CSC
);
3608 case UHF_C_PORT_ENABLE
:
3609 x
= URWMASK(UREAD2(sc
, port
));
3610 UWRITE2(sc
, port
, x
| UHCI_PORTSC_POEDC
);
3612 case UHF_C_PORT_OVER_CURRENT
:
3613 x
= URWMASK(UREAD2(sc
, port
));
3614 UWRITE2(sc
, port
, x
| UHCI_PORTSC_OCIC
);
3616 case UHF_C_PORT_RESET
:
3618 err
= USBD_NORMAL_COMPLETION
;
3620 case UHF_PORT_CONNECTION
:
3621 case UHF_PORT_OVER_CURRENT
:
3622 case UHF_PORT_POWER
:
3623 case UHF_PORT_LOW_SPEED
:
3624 case UHF_C_PORT_SUSPEND
:
3630 case C(UR_GET_BUS_STATE
, UT_READ_CLASS_OTHER
):
3632 port
= UHCI_PORTSC1
;
3633 else if (index
== 2)
3634 port
= UHCI_PORTSC2
;
3641 (UREAD2(sc
, port
) & UHCI_PORTSC_LS
) >>
3642 UHCI_PORTSC_LS_SHIFT
;
3646 case C(UR_GET_DESCRIPTOR
, UT_READ_CLASS_DEVICE
):
3649 if ((value
& 0xff) != 0) {
3653 l
= min(len
, USB_HUB_DESCRIPTOR_SIZE
);
3655 memcpy(buf
, &uhci_hubd_piix
, l
);
3657 case C(UR_GET_STATUS
, UT_READ_CLASS_DEVICE
):
3662 memset(buf
, 0, len
);
3665 case C(UR_GET_STATUS
, UT_READ_CLASS_OTHER
):
3667 port
= UHCI_PORTSC1
;
3668 else if (index
== 2)
3669 port
= UHCI_PORTSC2
;
3678 x
= UREAD2(sc
, port
);
3679 status
= change
= 0;
3680 if (x
& UHCI_PORTSC_CCS
)
3681 status
|= UPS_CURRENT_CONNECT_STATUS
;
3682 if (x
& UHCI_PORTSC_CSC
)
3683 change
|= UPS_C_CONNECT_STATUS
;
3684 if (x
& UHCI_PORTSC_PE
)
3685 status
|= UPS_PORT_ENABLED
;
3686 if (x
& UHCI_PORTSC_POEDC
)
3687 change
|= UPS_C_PORT_ENABLED
;
3688 if (x
& UHCI_PORTSC_OCI
)
3689 status
|= UPS_OVERCURRENT_INDICATOR
;
3690 if (x
& UHCI_PORTSC_OCIC
)
3691 change
|= UPS_C_OVERCURRENT_INDICATOR
;
3692 if (x
& UHCI_PORTSC_SUSP
)
3693 status
|= UPS_SUSPEND
;
3694 if (x
& UHCI_PORTSC_LSDA
)
3695 status
|= UPS_LOW_SPEED
;
3696 status
|= UPS_PORT_POWER
;
3698 change
|= UPS_C_PORT_RESET
;
3699 USETW(ps
.wPortStatus
, status
);
3700 USETW(ps
.wPortChange
, change
);
3701 l
= min(len
, sizeof ps
);
3702 memcpy(buf
, &ps
, l
);
3705 case C(UR_SET_DESCRIPTOR
, UT_WRITE_CLASS_DEVICE
):
3708 case C(UR_SET_FEATURE
, UT_WRITE_CLASS_DEVICE
):
3710 case C(UR_SET_FEATURE
, UT_WRITE_CLASS_OTHER
):
3712 port
= UHCI_PORTSC1
;
3713 else if (index
== 2)
3714 port
= UHCI_PORTSC2
;
3720 case UHF_PORT_ENABLE
:
3721 x
= URWMASK(UREAD2(sc
, port
));
3722 UWRITE2(sc
, port
, x
| UHCI_PORTSC_PE
);
3724 case UHF_PORT_SUSPEND
:
3725 x
= URWMASK(UREAD2(sc
, port
));
3726 UWRITE2(sc
, port
, x
| UHCI_PORTSC_SUSP
);
3728 case UHF_PORT_RESET
:
3729 err
= uhci_portreset(sc
, index
);
3731 case UHF_PORT_POWER
:
3732 /* Pretend we turned on power */
3733 err
= USBD_NORMAL_COMPLETION
;
3735 case UHF_C_PORT_CONNECTION
:
3736 case UHF_C_PORT_ENABLE
:
3737 case UHF_C_PORT_OVER_CURRENT
:
3738 case UHF_PORT_CONNECTION
:
3739 case UHF_PORT_OVER_CURRENT
:
3740 case UHF_PORT_LOW_SPEED
:
3741 case UHF_C_PORT_SUSPEND
:
3742 case UHF_C_PORT_RESET
:
3752 xfer
->actlen
= totlen
;
3753 err
= USBD_NORMAL_COMPLETION
;
3757 usb_transfer_complete(xfer
);
3759 return (USBD_IN_PROGRESS
);
3762 /* Abort a root control request. */
3764 uhci_root_ctrl_abort(usbd_xfer_handle xfer
)
3766 /* Nothing to do, all transfers are synchronous. */
3769 /* Close the root pipe. */
3771 uhci_root_ctrl_close(usbd_pipe_handle pipe
)
3773 DPRINTF(("uhci_root_ctrl_close\n"));
3776 /* Abort a root interrupt request. */
3778 uhci_root_intr_abort(usbd_xfer_handle xfer
)
3780 uhci_softc_t
*sc
= xfer
->pipe
->device
->bus
->hci_private
;
3782 usb_uncallout(sc
->sc_poll_handle
, uhci_poll_hub
, xfer
);
3783 sc
->sc_intr_xfer
= NULL
;
3785 if (xfer
->pipe
->intrxfer
== xfer
) {
3786 DPRINTF(("uhci_root_intr_abort: remove\n"));
3787 xfer
->pipe
->intrxfer
= 0;
3789 xfer
->status
= USBD_CANCELLED
;
3791 UXFER(xfer
)->iinfo
.isdone
= 1;
3793 usb_transfer_complete(xfer
);
3797 uhci_root_intr_transfer(usbd_xfer_handle xfer
)
3801 /* Insert last in queue. */
3802 err
= usb_insert_transfer(xfer
);
3807 * Pipe isn't running (otherwise err would be USBD_INPROG),
3810 return (uhci_root_intr_start(SIMPLEQ_FIRST(&xfer
->pipe
->queue
)));
3813 /* Start a transfer on the root interrupt pipe */
3815 uhci_root_intr_start(usbd_xfer_handle xfer
)
3817 usbd_pipe_handle pipe
= xfer
->pipe
;
3818 uhci_softc_t
*sc
= pipe
->device
->bus
->hci_private
;
3821 DPRINTFN(3, ("uhci_root_intr_start: xfer=%p len=%d flags=%d\n",
3822 xfer
, xfer
->length
, xfer
->flags
));
3825 return (USBD_IOERROR
);
3827 /* XXX temporary variable needed to avoid gcc3 warning */
3828 ival
= xfer
->pipe
->endpoint
->edesc
->bInterval
;
3829 sc
->sc_ival
= mstohz(ival
);
3830 usb_callout(sc
->sc_poll_handle
, sc
->sc_ival
, uhci_poll_hub
, xfer
);
3831 sc
->sc_intr_xfer
= xfer
;
3832 return (USBD_IN_PROGRESS
);
3835 /* Close the root interrupt pipe. */
3837 uhci_root_intr_close(usbd_pipe_handle pipe
)
3839 uhci_softc_t
*sc
= pipe
->device
->bus
->hci_private
;
3841 usb_uncallout(sc
->sc_poll_handle
, uhci_poll_hub
, sc
->sc_intr_xfer
);
3842 sc
->sc_intr_xfer
= NULL
;
3843 DPRINTF(("uhci_root_intr_close\n"));