Sat May 2 22:28:41 2009 UTC ()
Correct previous: detaching uhubN makes the bus pointer NULL


(martin)
diff -r1.227 -r1.228 src/sys/dev/usb/uhci.c

cvs diff -r1.227 -r1.228 src/sys/dev/usb/uhci.c (switch to unified diff)

--- src/sys/dev/usb/uhci.c 2009/05/02 22:09:39 1.227
+++ src/sys/dev/usb/uhci.c 2009/05/02 22:28:41 1.228
@@ -1,2042 +1,2043 @@ @@ -1,2042 +1,2043 @@
1/* $NetBSD: uhci.c,v 1.227 2009/05/02 22:09:39 martin Exp $ */ 1/* $NetBSD: uhci.c,v 1.228 2009/05/02 22:28:41 martin Exp $ */
2/* $FreeBSD: src/sys/dev/usb/uhci.c,v 1.33 1999/11/17 22:33:41 n_hibma Exp $ */ 2/* $FreeBSD: src/sys/dev/usb/uhci.c,v 1.33 1999/11/17 22:33:41 n_hibma Exp $ */
3 3
4/* 4/*
5 * Copyright (c) 1998, 2004 The NetBSD Foundation, Inc. 5 * Copyright (c) 1998, 2004 The NetBSD Foundation, Inc.
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * This code is derived from software contributed to The NetBSD Foundation 8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Lennart Augustsson (lennart@augustsson.net) at 9 * by Lennart Augustsson (lennart@augustsson.net) at
10 * Carlstedt Research & Technology. 10 * Carlstedt Research & Technology.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions 13 * modification, are permitted provided that the following conditions
14 * are met: 14 * are met:
15 * 1. Redistributions of source code must retain the above copyright 15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer. 16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright 17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the 18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution. 19 * documentation and/or other materials provided with the distribution.
20 * 20 *
21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 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 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 23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 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 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE. 31 * POSSIBILITY OF SUCH DAMAGE.
32 */ 32 */
33 33
34/* 34/*
35 * USB Universal Host Controller driver. 35 * USB Universal Host Controller driver.
36 * Handles e.g. PIIX3 and PIIX4. 36 * Handles e.g. PIIX3 and PIIX4.
37 * 37 *
38 * UHCI spec: http://developer.intel.com/design/USB/UHCI11D.htm 38 * UHCI spec: http://developer.intel.com/design/USB/UHCI11D.htm
39 * USB spec: http://www.usb.org/developers/docs/usbspec.zip 39 * USB spec: http://www.usb.org/developers/docs/usbspec.zip
40 * PIIXn spec: ftp://download.intel.com/design/intarch/datashts/29055002.pdf 40 * PIIXn spec: ftp://download.intel.com/design/intarch/datashts/29055002.pdf
41 * ftp://download.intel.com/design/intarch/datashts/29056201.pdf 41 * ftp://download.intel.com/design/intarch/datashts/29056201.pdf
42 */ 42 */
43 43
44#include <sys/cdefs.h> 44#include <sys/cdefs.h>
45__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.227 2009/05/02 22:09:39 martin Exp $"); 45__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.228 2009/05/02 22:28:41 martin Exp $");
46 46
47#include <sys/param.h> 47#include <sys/param.h>
48#include <sys/systm.h> 48#include <sys/systm.h>
49#include <sys/kernel.h> 49#include <sys/kernel.h>
50#include <sys/malloc.h> 50#include <sys/malloc.h>
51#if defined(__NetBSD__) || defined(__OpenBSD__) 51#if defined(__NetBSD__) || defined(__OpenBSD__)
52#include <sys/device.h> 52#include <sys/device.h>
53#include <sys/select.h> 53#include <sys/select.h>
54#include <sys/extent.h> 54#include <sys/extent.h>
55#include <uvm/uvm_extern.h> 55#include <uvm/uvm_extern.h>
56#elif defined(__FreeBSD__) 56#elif defined(__FreeBSD__)
57#include <sys/module.h> 57#include <sys/module.h>
58#include <sys/bus.h> 58#include <sys/bus.h>
59#include <machine/bus_pio.h> 59#include <machine/bus_pio.h>
60#if defined(DIAGNOSTIC) && defined(__i386__) 60#if defined(DIAGNOSTIC) && defined(__i386__)
61#include <sys/cpu.h> 61#include <sys/cpu.h>
62#endif 62#endif
63#endif 63#endif
64#include <sys/proc.h> 64#include <sys/proc.h>
65#include <sys/queue.h> 65#include <sys/queue.h>
66#include <sys/bus.h> 66#include <sys/bus.h>
67 67
68#include <machine/endian.h> 68#include <machine/endian.h>
69 69
70#include <dev/usb/usb.h> 70#include <dev/usb/usb.h>
71#include <dev/usb/usbdi.h> 71#include <dev/usb/usbdi.h>
72#include <dev/usb/usbdivar.h> 72#include <dev/usb/usbdivar.h>
73#include <dev/usb/usb_mem.h> 73#include <dev/usb/usb_mem.h>
74#include <dev/usb/usb_quirks.h> 74#include <dev/usb/usb_quirks.h>
75 75
76#include <dev/usb/uhcireg.h> 76#include <dev/usb/uhcireg.h>
77#include <dev/usb/uhcivar.h> 77#include <dev/usb/uhcivar.h>
78#include <dev/usb/usbroothub_subr.h> 78#include <dev/usb/usbroothub_subr.h>
79 79
80/* Use bandwidth reclamation for control transfers. Some devices choke on it. */ 80/* Use bandwidth reclamation for control transfers. Some devices choke on it. */
81/*#define UHCI_CTL_LOOP */ 81/*#define UHCI_CTL_LOOP */
82 82
83#if defined(__FreeBSD__) 83#if defined(__FreeBSD__)
84#include <machine/clock.h> 84#include <machine/clock.h>
85 85
86#define delay(d) DELAY(d) 86#define delay(d) DELAY(d)
87#endif 87#endif
88 88
89#if defined(__OpenBSD__) 89#if defined(__OpenBSD__)
90struct cfdriver uhci_cd = { 90struct cfdriver uhci_cd = {
91 NULL, "uhci", DV_DULL 91 NULL, "uhci", DV_DULL
92}; 92};
93#endif 93#endif
94 94
95#ifdef UHCI_DEBUG 95#ifdef UHCI_DEBUG
96uhci_softc_t *thesc; 96uhci_softc_t *thesc;
97#define DPRINTF(x) if (uhcidebug) printf x 97#define DPRINTF(x) if (uhcidebug) printf x
98#define DPRINTFN(n,x) if (uhcidebug>(n)) printf x 98#define DPRINTFN(n,x) if (uhcidebug>(n)) printf x
99int uhcidebug = 0; 99int uhcidebug = 0;
100int uhcinoloop = 0; 100int uhcinoloop = 0;
101#ifndef __NetBSD__ 101#ifndef __NetBSD__
102#define snprintb((q), (f), "%b", q,f,b,l) snprintf((b), (l)) 102#define snprintb((q), (f), "%b", q,f,b,l) snprintf((b), (l))
103#endif 103#endif
104#else 104#else
105#define DPRINTF(x) 105#define DPRINTF(x)
106#define DPRINTFN(n,x) 106#define DPRINTFN(n,x)
107#endif 107#endif
108 108
109/* 109/*
110 * The UHCI controller is little endian, so on big endian machines 110 * The UHCI controller is little endian, so on big endian machines
111 * the data stored in memory needs to be swapped. 111 * the data stored in memory needs to be swapped.
112 */ 112 */
113#if defined(__FreeBSD__) || defined(__OpenBSD__) 113#if defined(__FreeBSD__) || defined(__OpenBSD__)
114#if BYTE_ORDER == BIG_ENDIAN 114#if BYTE_ORDER == BIG_ENDIAN
115#define htole32(x) (bswap32(x)) 115#define htole32(x) (bswap32(x))
116#define le32toh(x) (bswap32(x)) 116#define le32toh(x) (bswap32(x))
117#else 117#else
118#define htole32(x) (x) 118#define htole32(x) (x)
119#define le32toh(x) (x) 119#define le32toh(x) (x)
120#endif 120#endif
121#endif 121#endif
122 122
123struct uhci_pipe { 123struct uhci_pipe {
124 struct usbd_pipe pipe; 124 struct usbd_pipe pipe;
125 int nexttoggle; 125 int nexttoggle;
126 126
127 u_char aborting; 127 u_char aborting;
128 usbd_xfer_handle abortstart, abortend; 128 usbd_xfer_handle abortstart, abortend;
129 129
130 /* Info needed for different pipe kinds. */ 130 /* Info needed for different pipe kinds. */
131 union { 131 union {
132 /* Control pipe */ 132 /* Control pipe */
133 struct { 133 struct {
134 uhci_soft_qh_t *sqh; 134 uhci_soft_qh_t *sqh;
135 usb_dma_t reqdma; 135 usb_dma_t reqdma;
136 uhci_soft_td_t *setup, *stat; 136 uhci_soft_td_t *setup, *stat;
137 u_int length; 137 u_int length;
138 } ctl; 138 } ctl;
139 /* Interrupt pipe */ 139 /* Interrupt pipe */
140 struct { 140 struct {
141 int npoll; 141 int npoll;
142 int isread; 142 int isread;
143 uhci_soft_qh_t **qhs; 143 uhci_soft_qh_t **qhs;
144 } intr; 144 } intr;
145 /* Bulk pipe */ 145 /* Bulk pipe */
146 struct { 146 struct {
147 uhci_soft_qh_t *sqh; 147 uhci_soft_qh_t *sqh;
148 u_int length; 148 u_int length;
149 int isread; 149 int isread;
150 } bulk; 150 } bulk;
151 /* Iso pipe */ 151 /* Iso pipe */
152 struct iso { 152 struct iso {
153 uhci_soft_td_t **stds; 153 uhci_soft_td_t **stds;
154 int next, inuse; 154 int next, inuse;
155 } iso; 155 } iso;
156 } u; 156 } u;
157}; 157};
158 158
159Static void uhci_globalreset(uhci_softc_t *); 159Static void uhci_globalreset(uhci_softc_t *);
160Static usbd_status uhci_portreset(uhci_softc_t*, int); 160Static usbd_status uhci_portreset(uhci_softc_t*, int);
161Static void uhci_reset(uhci_softc_t *); 161Static void uhci_reset(uhci_softc_t *);
162Static usbd_status uhci_run(uhci_softc_t *, int run); 162Static usbd_status uhci_run(uhci_softc_t *, int run);
163Static uhci_soft_td_t *uhci_alloc_std(uhci_softc_t *); 163Static uhci_soft_td_t *uhci_alloc_std(uhci_softc_t *);
164Static void uhci_free_std(uhci_softc_t *, uhci_soft_td_t *); 164Static void uhci_free_std(uhci_softc_t *, uhci_soft_td_t *);
165Static uhci_soft_qh_t *uhci_alloc_sqh(uhci_softc_t *); 165Static uhci_soft_qh_t *uhci_alloc_sqh(uhci_softc_t *);
166Static void uhci_free_sqh(uhci_softc_t *, uhci_soft_qh_t *); 166Static void uhci_free_sqh(uhci_softc_t *, uhci_soft_qh_t *);
167#if 0 167#if 0
168Static void uhci_enter_ctl_q(uhci_softc_t *, uhci_soft_qh_t *, 168Static void uhci_enter_ctl_q(uhci_softc_t *, uhci_soft_qh_t *,
169 uhci_intr_info_t *); 169 uhci_intr_info_t *);
170Static void uhci_exit_ctl_q(uhci_softc_t *, uhci_soft_qh_t *); 170Static void uhci_exit_ctl_q(uhci_softc_t *, uhci_soft_qh_t *);
171#endif 171#endif
172 172
173Static void uhci_free_std_chain(uhci_softc_t *, 173Static void uhci_free_std_chain(uhci_softc_t *,
174 uhci_soft_td_t *, uhci_soft_td_t *); 174 uhci_soft_td_t *, uhci_soft_td_t *);
175Static usbd_status uhci_alloc_std_chain(struct uhci_pipe *, 175Static usbd_status uhci_alloc_std_chain(struct uhci_pipe *,
176 uhci_softc_t *, int, int, u_int16_t, usb_dma_t *, 176 uhci_softc_t *, int, int, u_int16_t, usb_dma_t *,
177 uhci_soft_td_t **, uhci_soft_td_t **); 177 uhci_soft_td_t **, uhci_soft_td_t **);
178Static void uhci_poll_hub(void *); 178Static void uhci_poll_hub(void *);
179Static void uhci_waitintr(uhci_softc_t *, usbd_xfer_handle); 179Static void uhci_waitintr(uhci_softc_t *, usbd_xfer_handle);
180Static void uhci_check_intr(uhci_softc_t *, uhci_intr_info_t *); 180Static void uhci_check_intr(uhci_softc_t *, uhci_intr_info_t *);
181Static void uhci_idone(uhci_intr_info_t *); 181Static void uhci_idone(uhci_intr_info_t *);
182 182
183Static void uhci_abort_xfer(usbd_xfer_handle, usbd_status status); 183Static void uhci_abort_xfer(usbd_xfer_handle, usbd_status status);
184 184
185Static void uhci_timeout(void *); 185Static void uhci_timeout(void *);
186Static void uhci_timeout_task(void *); 186Static void uhci_timeout_task(void *);
187Static void uhci_add_ls_ctrl(uhci_softc_t *, uhci_soft_qh_t *); 187Static void uhci_add_ls_ctrl(uhci_softc_t *, uhci_soft_qh_t *);
188Static void uhci_add_hs_ctrl(uhci_softc_t *, uhci_soft_qh_t *); 188Static void uhci_add_hs_ctrl(uhci_softc_t *, uhci_soft_qh_t *);
189Static void uhci_add_bulk(uhci_softc_t *, uhci_soft_qh_t *); 189Static void uhci_add_bulk(uhci_softc_t *, uhci_soft_qh_t *);
190Static void uhci_remove_ls_ctrl(uhci_softc_t *,uhci_soft_qh_t *); 190Static void uhci_remove_ls_ctrl(uhci_softc_t *,uhci_soft_qh_t *);
191Static void uhci_remove_hs_ctrl(uhci_softc_t *,uhci_soft_qh_t *); 191Static void uhci_remove_hs_ctrl(uhci_softc_t *,uhci_soft_qh_t *);
192Static void uhci_remove_bulk(uhci_softc_t *,uhci_soft_qh_t *); 192Static void uhci_remove_bulk(uhci_softc_t *,uhci_soft_qh_t *);
193Static void uhci_add_loop(uhci_softc_t *sc); 193Static void uhci_add_loop(uhci_softc_t *sc);
194Static void uhci_rem_loop(uhci_softc_t *sc); 194Static void uhci_rem_loop(uhci_softc_t *sc);
195 195
196Static usbd_status uhci_setup_isoc(usbd_pipe_handle pipe); 196Static usbd_status uhci_setup_isoc(usbd_pipe_handle pipe);
197Static void uhci_device_isoc_enter(usbd_xfer_handle); 197Static void uhci_device_isoc_enter(usbd_xfer_handle);
198 198
199Static usbd_status uhci_allocm(struct usbd_bus *, usb_dma_t *, u_int32_t); 199Static usbd_status uhci_allocm(struct usbd_bus *, usb_dma_t *, u_int32_t);
200Static void uhci_freem(struct usbd_bus *, usb_dma_t *); 200Static void uhci_freem(struct usbd_bus *, usb_dma_t *);
201 201
202Static usbd_xfer_handle uhci_allocx(struct usbd_bus *); 202Static usbd_xfer_handle uhci_allocx(struct usbd_bus *);
203Static void uhci_freex(struct usbd_bus *, usbd_xfer_handle); 203Static void uhci_freex(struct usbd_bus *, usbd_xfer_handle);
204 204
205Static usbd_status uhci_device_ctrl_transfer(usbd_xfer_handle); 205Static usbd_status uhci_device_ctrl_transfer(usbd_xfer_handle);
206Static usbd_status uhci_device_ctrl_start(usbd_xfer_handle); 206Static usbd_status uhci_device_ctrl_start(usbd_xfer_handle);
207Static void uhci_device_ctrl_abort(usbd_xfer_handle); 207Static void uhci_device_ctrl_abort(usbd_xfer_handle);
208Static void uhci_device_ctrl_close(usbd_pipe_handle); 208Static void uhci_device_ctrl_close(usbd_pipe_handle);
209Static void uhci_device_ctrl_done(usbd_xfer_handle); 209Static void uhci_device_ctrl_done(usbd_xfer_handle);
210 210
211Static usbd_status uhci_device_intr_transfer(usbd_xfer_handle); 211Static usbd_status uhci_device_intr_transfer(usbd_xfer_handle);
212Static usbd_status uhci_device_intr_start(usbd_xfer_handle); 212Static usbd_status uhci_device_intr_start(usbd_xfer_handle);
213Static void uhci_device_intr_abort(usbd_xfer_handle); 213Static void uhci_device_intr_abort(usbd_xfer_handle);
214Static void uhci_device_intr_close(usbd_pipe_handle); 214Static void uhci_device_intr_close(usbd_pipe_handle);
215Static void uhci_device_intr_done(usbd_xfer_handle); 215Static void uhci_device_intr_done(usbd_xfer_handle);
216 216
217Static usbd_status uhci_device_bulk_transfer(usbd_xfer_handle); 217Static usbd_status uhci_device_bulk_transfer(usbd_xfer_handle);
218Static usbd_status uhci_device_bulk_start(usbd_xfer_handle); 218Static usbd_status uhci_device_bulk_start(usbd_xfer_handle);
219Static void uhci_device_bulk_abort(usbd_xfer_handle); 219Static void uhci_device_bulk_abort(usbd_xfer_handle);
220Static void uhci_device_bulk_close(usbd_pipe_handle); 220Static void uhci_device_bulk_close(usbd_pipe_handle);
221Static void uhci_device_bulk_done(usbd_xfer_handle); 221Static void uhci_device_bulk_done(usbd_xfer_handle);
222 222
223Static usbd_status uhci_device_isoc_transfer(usbd_xfer_handle); 223Static usbd_status uhci_device_isoc_transfer(usbd_xfer_handle);
224Static usbd_status uhci_device_isoc_start(usbd_xfer_handle); 224Static usbd_status uhci_device_isoc_start(usbd_xfer_handle);
225Static void uhci_device_isoc_abort(usbd_xfer_handle); 225Static void uhci_device_isoc_abort(usbd_xfer_handle);
226Static void uhci_device_isoc_close(usbd_pipe_handle); 226Static void uhci_device_isoc_close(usbd_pipe_handle);
227Static void uhci_device_isoc_done(usbd_xfer_handle); 227Static void uhci_device_isoc_done(usbd_xfer_handle);
228 228
229Static usbd_status uhci_root_ctrl_transfer(usbd_xfer_handle); 229Static usbd_status uhci_root_ctrl_transfer(usbd_xfer_handle);
230Static usbd_status uhci_root_ctrl_start(usbd_xfer_handle); 230Static usbd_status uhci_root_ctrl_start(usbd_xfer_handle);
231Static void uhci_root_ctrl_abort(usbd_xfer_handle); 231Static void uhci_root_ctrl_abort(usbd_xfer_handle);
232Static void uhci_root_ctrl_close(usbd_pipe_handle); 232Static void uhci_root_ctrl_close(usbd_pipe_handle);
233Static void uhci_root_ctrl_done(usbd_xfer_handle); 233Static void uhci_root_ctrl_done(usbd_xfer_handle);
234 234
235Static usbd_status uhci_root_intr_transfer(usbd_xfer_handle); 235Static usbd_status uhci_root_intr_transfer(usbd_xfer_handle);
236Static usbd_status uhci_root_intr_start(usbd_xfer_handle); 236Static usbd_status uhci_root_intr_start(usbd_xfer_handle);
237Static void uhci_root_intr_abort(usbd_xfer_handle); 237Static void uhci_root_intr_abort(usbd_xfer_handle);
238Static void uhci_root_intr_close(usbd_pipe_handle); 238Static void uhci_root_intr_close(usbd_pipe_handle);
239Static void uhci_root_intr_done(usbd_xfer_handle); 239Static void uhci_root_intr_done(usbd_xfer_handle);
240 240
241Static usbd_status uhci_open(usbd_pipe_handle); 241Static usbd_status uhci_open(usbd_pipe_handle);
242Static void uhci_poll(struct usbd_bus *); 242Static void uhci_poll(struct usbd_bus *);
243Static void uhci_softintr(void *); 243Static void uhci_softintr(void *);
244 244
245Static usbd_status uhci_device_request(usbd_xfer_handle xfer); 245Static usbd_status uhci_device_request(usbd_xfer_handle xfer);
246 246
247Static void uhci_add_intr(uhci_softc_t *, uhci_soft_qh_t *); 247Static void uhci_add_intr(uhci_softc_t *, uhci_soft_qh_t *);
248Static void uhci_remove_intr(uhci_softc_t *, uhci_soft_qh_t *); 248Static void uhci_remove_intr(uhci_softc_t *, uhci_soft_qh_t *);
249Static usbd_status uhci_device_setintr(uhci_softc_t *sc, 249Static usbd_status uhci_device_setintr(uhci_softc_t *sc,
250 struct uhci_pipe *pipe, int ival); 250 struct uhci_pipe *pipe, int ival);
251 251
252Static void uhci_device_clear_toggle(usbd_pipe_handle pipe); 252Static void uhci_device_clear_toggle(usbd_pipe_handle pipe);
253Static void uhci_noop(usbd_pipe_handle pipe); 253Static void uhci_noop(usbd_pipe_handle pipe);
254 254
255Static inline uhci_soft_qh_t *uhci_find_prev_qh(uhci_soft_qh_t *, 255Static inline uhci_soft_qh_t *uhci_find_prev_qh(uhci_soft_qh_t *,
256 uhci_soft_qh_t *); 256 uhci_soft_qh_t *);
257 257
258#ifdef UHCI_DEBUG 258#ifdef UHCI_DEBUG
259Static void uhci_dump_all(uhci_softc_t *); 259Static void uhci_dump_all(uhci_softc_t *);
260Static void uhci_dumpregs(uhci_softc_t *); 260Static void uhci_dumpregs(uhci_softc_t *);
261Static void uhci_dump_qhs(uhci_soft_qh_t *); 261Static void uhci_dump_qhs(uhci_soft_qh_t *);
262Static void uhci_dump_qh(uhci_soft_qh_t *); 262Static void uhci_dump_qh(uhci_soft_qh_t *);
263Static void uhci_dump_tds(uhci_soft_td_t *); 263Static void uhci_dump_tds(uhci_soft_td_t *);
264Static void uhci_dump_td(uhci_soft_td_t *); 264Static void uhci_dump_td(uhci_soft_td_t *);
265Static void uhci_dump_ii(uhci_intr_info_t *ii); 265Static void uhci_dump_ii(uhci_intr_info_t *ii);
266void uhci_dump(void); 266void uhci_dump(void);
267#endif 267#endif
268 268
269#define UBARR(sc) bus_space_barrier((sc)->iot, (sc)->ioh, 0, (sc)->sc_size, \ 269#define UBARR(sc) bus_space_barrier((sc)->iot, (sc)->ioh, 0, (sc)->sc_size, \
270 BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE) 270 BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE)
271#define UWRITE1(sc, r, x) \ 271#define UWRITE1(sc, r, x) \
272 do { UBARR(sc); bus_space_write_1((sc)->iot, (sc)->ioh, (r), (x)); \ 272 do { UBARR(sc); bus_space_write_1((sc)->iot, (sc)->ioh, (r), (x)); \
273 } while (/*CONSTCOND*/0) 273 } while (/*CONSTCOND*/0)
274#define UWRITE2(sc, r, x) \ 274#define UWRITE2(sc, r, x) \
275 do { UBARR(sc); bus_space_write_2((sc)->iot, (sc)->ioh, (r), (x)); \ 275 do { UBARR(sc); bus_space_write_2((sc)->iot, (sc)->ioh, (r), (x)); \
276 } while (/*CONSTCOND*/0) 276 } while (/*CONSTCOND*/0)
277#define UWRITE4(sc, r, x) \ 277#define UWRITE4(sc, r, x) \
278 do { UBARR(sc); bus_space_write_4((sc)->iot, (sc)->ioh, (r), (x)); \ 278 do { UBARR(sc); bus_space_write_4((sc)->iot, (sc)->ioh, (r), (x)); \
279 } while (/*CONSTCOND*/0) 279 } while (/*CONSTCOND*/0)
280static __inline uint8_t 280static __inline uint8_t
281UREAD1(uhci_softc_t *sc, bus_size_t r) 281UREAD1(uhci_softc_t *sc, bus_size_t r)
282{ 282{
283 283
284 UBARR(sc); 284 UBARR(sc);
285 return bus_space_read_1(sc->iot, sc->ioh, r); 285 return bus_space_read_1(sc->iot, sc->ioh, r);
286} 286}
287 287
288static __inline uint16_t 288static __inline uint16_t
289UREAD2(uhci_softc_t *sc, bus_size_t r) 289UREAD2(uhci_softc_t *sc, bus_size_t r)
290{ 290{
291 291
292 UBARR(sc); 292 UBARR(sc);
293 return bus_space_read_2(sc->iot, sc->ioh, r); 293 return bus_space_read_2(sc->iot, sc->ioh, r);
294} 294}
295 295
296static __inline uint32_t 296static __inline uint32_t
297UREAD4(uhci_softc_t *sc, bus_size_t r) 297UREAD4(uhci_softc_t *sc, bus_size_t r)
298{ 298{
299 299
300 UBARR(sc); 300 UBARR(sc);
301 return bus_space_read_4(sc->iot, sc->ioh, r); 301 return bus_space_read_4(sc->iot, sc->ioh, r);
302} 302}
303 303
304#define UHCICMD(sc, cmd) UWRITE2(sc, UHCI_CMD, cmd) 304#define UHCICMD(sc, cmd) UWRITE2(sc, UHCI_CMD, cmd)
305#define UHCISTS(sc) UREAD2(sc, UHCI_STS) 305#define UHCISTS(sc) UREAD2(sc, UHCI_STS)
306 306
307#define UHCI_RESET_TIMEOUT 100 /* ms, reset timeout */ 307#define UHCI_RESET_TIMEOUT 100 /* ms, reset timeout */
308 308
309#define UHCI_CURFRAME(sc) (UREAD2(sc, UHCI_FRNUM) & UHCI_FRNUM_MASK) 309#define UHCI_CURFRAME(sc) (UREAD2(sc, UHCI_FRNUM) & UHCI_FRNUM_MASK)
310 310
311#define UHCI_INTR_ENDPT 1 311#define UHCI_INTR_ENDPT 1
312 312
313const struct usbd_bus_methods uhci_bus_methods = { 313const struct usbd_bus_methods uhci_bus_methods = {
314 uhci_open, 314 uhci_open,
315 uhci_softintr, 315 uhci_softintr,
316 uhci_poll, 316 uhci_poll,
317 uhci_allocm, 317 uhci_allocm,
318 uhci_freem, 318 uhci_freem,
319 uhci_allocx, 319 uhci_allocx,
320 uhci_freex, 320 uhci_freex,
321}; 321};
322 322
323const struct usbd_pipe_methods uhci_root_ctrl_methods = { 323const struct usbd_pipe_methods uhci_root_ctrl_methods = {
324 uhci_root_ctrl_transfer, 324 uhci_root_ctrl_transfer,
325 uhci_root_ctrl_start, 325 uhci_root_ctrl_start,
326 uhci_root_ctrl_abort, 326 uhci_root_ctrl_abort,
327 uhci_root_ctrl_close, 327 uhci_root_ctrl_close,
328 uhci_noop, 328 uhci_noop,
329 uhci_root_ctrl_done, 329 uhci_root_ctrl_done,
330}; 330};
331 331
332const struct usbd_pipe_methods uhci_root_intr_methods = { 332const struct usbd_pipe_methods uhci_root_intr_methods = {
333 uhci_root_intr_transfer, 333 uhci_root_intr_transfer,
334 uhci_root_intr_start, 334 uhci_root_intr_start,
335 uhci_root_intr_abort, 335 uhci_root_intr_abort,
336 uhci_root_intr_close, 336 uhci_root_intr_close,
337 uhci_noop, 337 uhci_noop,
338 uhci_root_intr_done, 338 uhci_root_intr_done,
339}; 339};
340 340
341const struct usbd_pipe_methods uhci_device_ctrl_methods = { 341const struct usbd_pipe_methods uhci_device_ctrl_methods = {
342 uhci_device_ctrl_transfer, 342 uhci_device_ctrl_transfer,
343 uhci_device_ctrl_start, 343 uhci_device_ctrl_start,
344 uhci_device_ctrl_abort, 344 uhci_device_ctrl_abort,
345 uhci_device_ctrl_close, 345 uhci_device_ctrl_close,
346 uhci_noop, 346 uhci_noop,
347 uhci_device_ctrl_done, 347 uhci_device_ctrl_done,
348}; 348};
349 349
350const struct usbd_pipe_methods uhci_device_intr_methods = { 350const struct usbd_pipe_methods uhci_device_intr_methods = {
351 uhci_device_intr_transfer, 351 uhci_device_intr_transfer,
352 uhci_device_intr_start, 352 uhci_device_intr_start,
353 uhci_device_intr_abort, 353 uhci_device_intr_abort,
354 uhci_device_intr_close, 354 uhci_device_intr_close,
355 uhci_device_clear_toggle, 355 uhci_device_clear_toggle,
356 uhci_device_intr_done, 356 uhci_device_intr_done,
357}; 357};
358 358
359const struct usbd_pipe_methods uhci_device_bulk_methods = { 359const struct usbd_pipe_methods uhci_device_bulk_methods = {
360 uhci_device_bulk_transfer, 360 uhci_device_bulk_transfer,
361 uhci_device_bulk_start, 361 uhci_device_bulk_start,
362 uhci_device_bulk_abort, 362 uhci_device_bulk_abort,
363 uhci_device_bulk_close, 363 uhci_device_bulk_close,
364 uhci_device_clear_toggle, 364 uhci_device_clear_toggle,
365 uhci_device_bulk_done, 365 uhci_device_bulk_done,
366}; 366};
367 367
368const struct usbd_pipe_methods uhci_device_isoc_methods = { 368const struct usbd_pipe_methods uhci_device_isoc_methods = {
369 uhci_device_isoc_transfer, 369 uhci_device_isoc_transfer,
370 uhci_device_isoc_start, 370 uhci_device_isoc_start,
371 uhci_device_isoc_abort, 371 uhci_device_isoc_abort,
372 uhci_device_isoc_close, 372 uhci_device_isoc_close,
373 uhci_noop, 373 uhci_noop,
374 uhci_device_isoc_done, 374 uhci_device_isoc_done,
375}; 375};
376 376
377#define uhci_add_intr_info(sc, ii) \ 377#define uhci_add_intr_info(sc, ii) \
378 LIST_INSERT_HEAD(&(sc)->sc_intrhead, (ii), list) 378 LIST_INSERT_HEAD(&(sc)->sc_intrhead, (ii), list)
379#define uhci_del_intr_info(ii) \ 379#define uhci_del_intr_info(ii) \
380 do { \ 380 do { \
381 LIST_REMOVE((ii), list); \ 381 LIST_REMOVE((ii), list); \
382 (ii)->list.le_prev = NULL; \ 382 (ii)->list.le_prev = NULL; \
383 } while (0) 383 } while (0)
384#define uhci_active_intr_info(ii) ((ii)->list.le_prev != NULL) 384#define uhci_active_intr_info(ii) ((ii)->list.le_prev != NULL)
385 385
386Static inline uhci_soft_qh_t * 386Static inline uhci_soft_qh_t *
387uhci_find_prev_qh(uhci_soft_qh_t *pqh, uhci_soft_qh_t *sqh) 387uhci_find_prev_qh(uhci_soft_qh_t *pqh, uhci_soft_qh_t *sqh)
388{ 388{
389 DPRINTFN(15,("uhci_find_prev_qh: pqh=%p sqh=%p\n", pqh, sqh)); 389 DPRINTFN(15,("uhci_find_prev_qh: pqh=%p sqh=%p\n", pqh, sqh));
390 390
391 for (; pqh->hlink != sqh; pqh = pqh->hlink) { 391 for (; pqh->hlink != sqh; pqh = pqh->hlink) {
392#if defined(DIAGNOSTIC) || defined(UHCI_DEBUG) 392#if defined(DIAGNOSTIC) || defined(UHCI_DEBUG)
393 usb_syncmem(&pqh->dma, 393 usb_syncmem(&pqh->dma,
394 pqh->offs + offsetof(uhci_qh_t, qh_hlink), 394 pqh->offs + offsetof(uhci_qh_t, qh_hlink),
395 sizeof(pqh->qh.qh_hlink), 395 sizeof(pqh->qh.qh_hlink),
396 BUS_DMASYNC_POSTWRITE); 396 BUS_DMASYNC_POSTWRITE);
397 if (le32toh(pqh->qh.qh_hlink) & UHCI_PTR_T) { 397 if (le32toh(pqh->qh.qh_hlink) & UHCI_PTR_T) {
398 printf("uhci_find_prev_qh: QH not found\n"); 398 printf("uhci_find_prev_qh: QH not found\n");
399 return (NULL); 399 return (NULL);
400 } 400 }
401#endif 401#endif
402 } 402 }
403 return (pqh); 403 return (pqh);
404} 404}
405 405
406void 406void
407uhci_globalreset(uhci_softc_t *sc) 407uhci_globalreset(uhci_softc_t *sc)
408{ 408{
409 UHCICMD(sc, UHCI_CMD_GRESET); /* global reset */ 409 UHCICMD(sc, UHCI_CMD_GRESET); /* global reset */
410 usb_delay_ms(&sc->sc_bus, USB_BUS_RESET_DELAY); /* wait a little */ 410 usb_delay_ms(&sc->sc_bus, USB_BUS_RESET_DELAY); /* wait a little */
411 UHCICMD(sc, 0); /* do nothing */ 411 UHCICMD(sc, 0); /* do nothing */
412} 412}
413 413
414usbd_status 414usbd_status
415uhci_init(uhci_softc_t *sc) 415uhci_init(uhci_softc_t *sc)
416{ 416{
417 usbd_status err; 417 usbd_status err;
418 int i, j; 418 int i, j;
419 uhci_soft_qh_t *clsqh, *chsqh, *bsqh, *sqh, *lsqh; 419 uhci_soft_qh_t *clsqh, *chsqh, *bsqh, *sqh, *lsqh;
420 uhci_soft_td_t *std; 420 uhci_soft_td_t *std;
421 421
422 DPRINTFN(1,("uhci_init: start\n")); 422 DPRINTFN(1,("uhci_init: start\n"));
423 423
424#ifdef UHCI_DEBUG 424#ifdef UHCI_DEBUG
425 thesc = sc; 425 thesc = sc;
426 426
427 if (uhcidebug > 2) 427 if (uhcidebug > 2)
428 uhci_dumpregs(sc); 428 uhci_dumpregs(sc);
429#endif 429#endif
430 430
431 sc->sc_suspend = PWR_RESUME; 431 sc->sc_suspend = PWR_RESUME;
432 432
433 UWRITE2(sc, UHCI_INTR, 0); /* disable interrupts */ 433 UWRITE2(sc, UHCI_INTR, 0); /* disable interrupts */
434 uhci_globalreset(sc); /* reset the controller */ 434 uhci_globalreset(sc); /* reset the controller */
435 uhci_reset(sc); 435 uhci_reset(sc);
436 436
437#ifdef __NetBSD__ 437#ifdef __NetBSD__
438 usb_setup_reserve(sc->sc_dev, &sc->sc_dma_reserve, sc->sc_bus.dmatag, 438 usb_setup_reserve(sc->sc_dev, &sc->sc_dma_reserve, sc->sc_bus.dmatag,
439 USB_MEM_RESERVE); 439 USB_MEM_RESERVE);
440#endif 440#endif
441 441
442 /* Allocate and initialize real frame array. */ 442 /* Allocate and initialize real frame array. */
443 err = usb_allocmem(&sc->sc_bus, 443 err = usb_allocmem(&sc->sc_bus,
444 UHCI_FRAMELIST_COUNT * sizeof(uhci_physaddr_t), 444 UHCI_FRAMELIST_COUNT * sizeof(uhci_physaddr_t),
445 UHCI_FRAMELIST_ALIGN, &sc->sc_dma); 445 UHCI_FRAMELIST_ALIGN, &sc->sc_dma);
446 if (err) 446 if (err)
447 return (err); 447 return (err);
448 sc->sc_pframes = KERNADDR(&sc->sc_dma, 0); 448 sc->sc_pframes = KERNADDR(&sc->sc_dma, 0);
449 UWRITE2(sc, UHCI_FRNUM, 0); /* set frame number to 0 */ 449 UWRITE2(sc, UHCI_FRNUM, 0); /* set frame number to 0 */
450 UWRITE4(sc, UHCI_FLBASEADDR, DMAADDR(&sc->sc_dma, 0)); /* set frame list*/ 450 UWRITE4(sc, UHCI_FLBASEADDR, DMAADDR(&sc->sc_dma, 0)); /* set frame list*/
451 451
452 /* 452 /*
453 * Allocate a TD, inactive, that hangs from the last QH. 453 * Allocate a TD, inactive, that hangs from the last QH.
454 * This is to avoid a bug in the PIIX that makes it run berserk 454 * This is to avoid a bug in the PIIX that makes it run berserk
455 * otherwise. 455 * otherwise.
456 */ 456 */
457 std = uhci_alloc_std(sc); 457 std = uhci_alloc_std(sc);
458 if (std == NULL) 458 if (std == NULL)
459 return (USBD_NOMEM); 459 return (USBD_NOMEM);
460 std->link.std = NULL; 460 std->link.std = NULL;
461 std->td.td_link = htole32(UHCI_PTR_T); 461 std->td.td_link = htole32(UHCI_PTR_T);
462 std->td.td_status = htole32(0); /* inactive */ 462 std->td.td_status = htole32(0); /* inactive */
463 std->td.td_token = htole32(0); 463 std->td.td_token = htole32(0);
464 std->td.td_buffer = htole32(0); 464 std->td.td_buffer = htole32(0);
465 usb_syncmem(&std->dma, std->offs, sizeof(std->td), 465 usb_syncmem(&std->dma, std->offs, sizeof(std->td),
466 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 466 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
467 467
468 /* Allocate the dummy QH marking the end and used for looping the QHs.*/ 468 /* Allocate the dummy QH marking the end and used for looping the QHs.*/
469 lsqh = uhci_alloc_sqh(sc); 469 lsqh = uhci_alloc_sqh(sc);
470 if (lsqh == NULL) 470 if (lsqh == NULL)
471 return (USBD_NOMEM); 471 return (USBD_NOMEM);
472 lsqh->hlink = NULL; 472 lsqh->hlink = NULL;
473 lsqh->qh.qh_hlink = htole32(UHCI_PTR_T); /* end of QH chain */ 473 lsqh->qh.qh_hlink = htole32(UHCI_PTR_T); /* end of QH chain */
474 lsqh->elink = std; 474 lsqh->elink = std;
475 lsqh->qh.qh_elink = htole32(std->physaddr | UHCI_PTR_TD); 475 lsqh->qh.qh_elink = htole32(std->physaddr | UHCI_PTR_TD);
476 sc->sc_last_qh = lsqh; 476 sc->sc_last_qh = lsqh;
477 usb_syncmem(&lsqh->dma, lsqh->offs, sizeof(lsqh->qh), 477 usb_syncmem(&lsqh->dma, lsqh->offs, sizeof(lsqh->qh),
478 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 478 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
479 479
480 /* Allocate the dummy QH where bulk traffic will be queued. */ 480 /* Allocate the dummy QH where bulk traffic will be queued. */
481 bsqh = uhci_alloc_sqh(sc); 481 bsqh = uhci_alloc_sqh(sc);
482 if (bsqh == NULL) 482 if (bsqh == NULL)
483 return (USBD_NOMEM); 483 return (USBD_NOMEM);
484 bsqh->hlink = lsqh; 484 bsqh->hlink = lsqh;
485 bsqh->qh.qh_hlink = htole32(lsqh->physaddr | UHCI_PTR_QH); 485 bsqh->qh.qh_hlink = htole32(lsqh->physaddr | UHCI_PTR_QH);
486 bsqh->elink = NULL; 486 bsqh->elink = NULL;
487 bsqh->qh.qh_elink = htole32(UHCI_PTR_T); 487 bsqh->qh.qh_elink = htole32(UHCI_PTR_T);
488 sc->sc_bulk_start = sc->sc_bulk_end = bsqh; 488 sc->sc_bulk_start = sc->sc_bulk_end = bsqh;
489 usb_syncmem(&bsqh->dma, bsqh->offs, sizeof(bsqh->qh), 489 usb_syncmem(&bsqh->dma, bsqh->offs, sizeof(bsqh->qh),
490 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 490 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
491 491
492 /* Allocate dummy QH where high speed control traffic will be queued. */ 492 /* Allocate dummy QH where high speed control traffic will be queued. */
493 chsqh = uhci_alloc_sqh(sc); 493 chsqh = uhci_alloc_sqh(sc);
494 if (chsqh == NULL) 494 if (chsqh == NULL)
495 return (USBD_NOMEM); 495 return (USBD_NOMEM);
496 chsqh->hlink = bsqh; 496 chsqh->hlink = bsqh;
497 chsqh->qh.qh_hlink = htole32(bsqh->physaddr | UHCI_PTR_QH); 497 chsqh->qh.qh_hlink = htole32(bsqh->physaddr | UHCI_PTR_QH);
498 chsqh->elink = NULL; 498 chsqh->elink = NULL;
499 chsqh->qh.qh_elink = htole32(UHCI_PTR_T); 499 chsqh->qh.qh_elink = htole32(UHCI_PTR_T);
500 sc->sc_hctl_start = sc->sc_hctl_end = chsqh; 500 sc->sc_hctl_start = sc->sc_hctl_end = chsqh;
501 usb_syncmem(&chsqh->dma, chsqh->offs, sizeof(chsqh->qh), 501 usb_syncmem(&chsqh->dma, chsqh->offs, sizeof(chsqh->qh),
502 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 502 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
503 503
504 /* Allocate dummy QH where control traffic will be queued. */ 504 /* Allocate dummy QH where control traffic will be queued. */
505 clsqh = uhci_alloc_sqh(sc); 505 clsqh = uhci_alloc_sqh(sc);
506 if (clsqh == NULL) 506 if (clsqh == NULL)
507 return (USBD_NOMEM); 507 return (USBD_NOMEM);
508 clsqh->hlink = chsqh; 508 clsqh->hlink = chsqh;
509 clsqh->qh.qh_hlink = htole32(chsqh->physaddr | UHCI_PTR_QH); 509 clsqh->qh.qh_hlink = htole32(chsqh->physaddr | UHCI_PTR_QH);
510 clsqh->elink = NULL; 510 clsqh->elink = NULL;
511 clsqh->qh.qh_elink = htole32(UHCI_PTR_T); 511 clsqh->qh.qh_elink = htole32(UHCI_PTR_T);
512 sc->sc_lctl_start = sc->sc_lctl_end = clsqh; 512 sc->sc_lctl_start = sc->sc_lctl_end = clsqh;
513 usb_syncmem(&clsqh->dma, clsqh->offs, sizeof(clsqh->qh), 513 usb_syncmem(&clsqh->dma, clsqh->offs, sizeof(clsqh->qh),
514 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 514 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
515 515
516 /* 516 /*
517 * Make all (virtual) frame list pointers point to the interrupt 517 * Make all (virtual) frame list pointers point to the interrupt
518 * queue heads and the interrupt queue heads at the control 518 * queue heads and the interrupt queue heads at the control
519 * queue head and point the physical frame list to the virtual. 519 * queue head and point the physical frame list to the virtual.
520 */ 520 */
521 for(i = 0; i < UHCI_VFRAMELIST_COUNT; i++) { 521 for(i = 0; i < UHCI_VFRAMELIST_COUNT; i++) {
522 std = uhci_alloc_std(sc); 522 std = uhci_alloc_std(sc);
523 sqh = uhci_alloc_sqh(sc); 523 sqh = uhci_alloc_sqh(sc);
524 if (std == NULL || sqh == NULL) 524 if (std == NULL || sqh == NULL)
525 return (USBD_NOMEM); 525 return (USBD_NOMEM);
526 std->link.sqh = sqh; 526 std->link.sqh = sqh;
527 std->td.td_link = htole32(sqh->physaddr | UHCI_PTR_QH); 527 std->td.td_link = htole32(sqh->physaddr | UHCI_PTR_QH);
528 std->td.td_status = htole32(UHCI_TD_IOS); /* iso, inactive */ 528 std->td.td_status = htole32(UHCI_TD_IOS); /* iso, inactive */
529 std->td.td_token = htole32(0); 529 std->td.td_token = htole32(0);
530 std->td.td_buffer = htole32(0); 530 std->td.td_buffer = htole32(0);
531 usb_syncmem(&std->dma, std->offs, sizeof(std->td), 531 usb_syncmem(&std->dma, std->offs, sizeof(std->td),
532 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 532 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
533 sqh->hlink = clsqh; 533 sqh->hlink = clsqh;
534 sqh->qh.qh_hlink = htole32(clsqh->physaddr | UHCI_PTR_QH); 534 sqh->qh.qh_hlink = htole32(clsqh->physaddr | UHCI_PTR_QH);
535 sqh->elink = NULL; 535 sqh->elink = NULL;
536 sqh->qh.qh_elink = htole32(UHCI_PTR_T); 536 sqh->qh.qh_elink = htole32(UHCI_PTR_T);
537 usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), 537 usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh),
538 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 538 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
539 sc->sc_vframes[i].htd = std; 539 sc->sc_vframes[i].htd = std;
540 sc->sc_vframes[i].etd = std; 540 sc->sc_vframes[i].etd = std;
541 sc->sc_vframes[i].hqh = sqh; 541 sc->sc_vframes[i].hqh = sqh;
542 sc->sc_vframes[i].eqh = sqh; 542 sc->sc_vframes[i].eqh = sqh;
543 for (j = i; 543 for (j = i;
544 j < UHCI_FRAMELIST_COUNT; 544 j < UHCI_FRAMELIST_COUNT;
545 j += UHCI_VFRAMELIST_COUNT) 545 j += UHCI_VFRAMELIST_COUNT)
546 sc->sc_pframes[j] = htole32(std->physaddr); 546 sc->sc_pframes[j] = htole32(std->physaddr);
547 } 547 }
548 usb_syncmem(&sc->sc_dma, 0, 548 usb_syncmem(&sc->sc_dma, 0,
549 UHCI_FRAMELIST_COUNT * sizeof(uhci_physaddr_t), 549 UHCI_FRAMELIST_COUNT * sizeof(uhci_physaddr_t),
550 BUS_DMASYNC_PREWRITE); 550 BUS_DMASYNC_PREWRITE);
551 551
552 552
553 LIST_INIT(&sc->sc_intrhead); 553 LIST_INIT(&sc->sc_intrhead);
554 554
555 SIMPLEQ_INIT(&sc->sc_free_xfers); 555 SIMPLEQ_INIT(&sc->sc_free_xfers);
556 556
557 usb_callout_init(sc->sc_poll_handle); 557 usb_callout_init(sc->sc_poll_handle);
558 558
559 /* Set up the bus struct. */ 559 /* Set up the bus struct. */
560 sc->sc_bus.methods = &uhci_bus_methods; 560 sc->sc_bus.methods = &uhci_bus_methods;
561 sc->sc_bus.pipe_size = sizeof(struct uhci_pipe); 561 sc->sc_bus.pipe_size = sizeof(struct uhci_pipe);
562 562
563 UHCICMD(sc, UHCI_CMD_MAXP); /* Assume 64 byte packets at frame end */ 563 UHCICMD(sc, UHCI_CMD_MAXP); /* Assume 64 byte packets at frame end */
564 564
565 DPRINTFN(1,("uhci_init: enabling\n")); 565 DPRINTFN(1,("uhci_init: enabling\n"));
566 566
567 err = uhci_run(sc, 1); /* and here we go... */ 567 err = uhci_run(sc, 1); /* and here we go... */
568 UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE | UHCI_INTR_RIE | 568 UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE | UHCI_INTR_RIE |
569 UHCI_INTR_IOCE | UHCI_INTR_SPIE); /* enable interrupts */ 569 UHCI_INTR_IOCE | UHCI_INTR_SPIE); /* enable interrupts */
570 return err; 570 return err;
571} 571}
572 572
573#if defined(__NetBSD__) || defined(__OpenBSD__) 573#if defined(__NetBSD__) || defined(__OpenBSD__)
574int 574int
575uhci_activate(device_t self, enum devact act) 575uhci_activate(device_t self, enum devact act)
576{ 576{
577 struct uhci_softc *sc = device_private(self); 577 struct uhci_softc *sc = device_private(self);
578 int rv = 0; 578 int rv = 0;
579 579
580 switch (act) { 580 switch (act) {
581 case DVACT_ACTIVATE: 581 case DVACT_ACTIVATE:
582 return (EOPNOTSUPP); 582 return (EOPNOTSUPP);
583 583
584 case DVACT_DEACTIVATE: 584 case DVACT_DEACTIVATE:
585 sc->sc_dying = 1; 585 sc->sc_dying = 1;
586 if (sc->sc_child != NULL) 586 if (sc->sc_child != NULL)
587 rv = config_deactivate(sc->sc_child); 587 rv = config_deactivate(sc->sc_child);
588 break; 588 break;
589 } 589 }
590 return (rv); 590 return (rv);
591} 591}
592 592
593void 593void
594uhci_childdet(device_t self, device_t child) 594uhci_childdet(device_t self, device_t child)
595{ 595{
596 struct uhci_softc *sc = device_private(self); 596 struct uhci_softc *sc = device_private(self);
597 597
598 KASSERT(sc->sc_child == child); 598 KASSERT(sc->sc_child == child);
599 sc->sc_child = NULL; 599 sc->sc_child = NULL;
600} 600}
601 601
602int 602int
603uhci_detach(struct uhci_softc *sc, int flags) 603uhci_detach(struct uhci_softc *sc, int flags)
604{ 604{
605 usbd_xfer_handle xfer; 605 usbd_xfer_handle xfer;
606 int rv = 0; 606 int rv = 0;
607 607
608 if (sc->sc_child != NULL) 608 if (sc->sc_child != NULL)
609 rv = config_detach(sc->sc_child, flags); 609 rv = config_detach(sc->sc_child, flags);
610 610
611 if (rv != 0) 611 if (rv != 0)
612 return (rv); 612 return (rv);
613 613
614 /* Free all xfers associated with this HC. */ 614 /* Free all xfers associated with this HC. */
615 for (;;) { 615 for (;;) {
616 xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers); 616 xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers);
617 if (xfer == NULL) 617 if (xfer == NULL)
618 break; 618 break;
619 SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, next); 619 SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, next);
620 free(xfer, M_USB); 620 free(xfer, M_USB);
621 } 621 }
622 622
623 callout_halt(&sc->sc_poll_handle, NULL); 623 callout_halt(&sc->sc_poll_handle, NULL);
624 callout_destroy(&sc->sc_poll_handle); 624 callout_destroy(&sc->sc_poll_handle);
625 625
626 /* XXX free other data structures XXX */ 626 /* XXX free other data structures XXX */
627 627
628 return (rv); 628 return (rv);
629} 629}
630#endif 630#endif
631 631
632usbd_status 632usbd_status
633uhci_allocm(struct usbd_bus *bus, usb_dma_t *dma, u_int32_t size) 633uhci_allocm(struct usbd_bus *bus, usb_dma_t *dma, u_int32_t size)
634{ 634{
635 struct uhci_softc *sc = bus->hci_private; 635 struct uhci_softc *sc = bus->hci_private;
636 usbd_status status; 636 usbd_status status;
637 u_int32_t n; 637 u_int32_t n;
638 638
639 /* 639 /*
640 * XXX 640 * XXX
641 * Since we are allocating a buffer we can assume that we will 641 * Since we are allocating a buffer we can assume that we will
642 * need TDs for it. Since we don't want to allocate those from 642 * need TDs for it. Since we don't want to allocate those from
643 * an interrupt context, we allocate them here and free them again. 643 * an interrupt context, we allocate them here and free them again.
644 * This is no guarantee that we'll get the TDs next time... 644 * This is no guarantee that we'll get the TDs next time...
645 */ 645 */
646 n = size / 8; 646 n = size / 8;
647 if (n > 16) { 647 if (n > 16) {
648 u_int32_t i; 648 u_int32_t i;
649 uhci_soft_td_t **stds; 649 uhci_soft_td_t **stds;
650 DPRINTF(("uhci_allocm: get %d TDs\n", n)); 650 DPRINTF(("uhci_allocm: get %d TDs\n", n));
651 stds = malloc(sizeof(uhci_soft_td_t *) * n, M_TEMP, 651 stds = malloc(sizeof(uhci_soft_td_t *) * n, M_TEMP,
652 M_WAITOK|M_ZERO); 652 M_WAITOK|M_ZERO);
653 for(i=0; i < n; i++) 653 for(i=0; i < n; i++)
654 stds[i] = uhci_alloc_std(sc); 654 stds[i] = uhci_alloc_std(sc);
655 for(i=0; i < n; i++) 655 for(i=0; i < n; i++)
656 if (stds[i] != NULL) 656 if (stds[i] != NULL)
657 uhci_free_std(sc, stds[i]); 657 uhci_free_std(sc, stds[i]);
658 free(stds, M_TEMP); 658 free(stds, M_TEMP);
659 } 659 }
660 660
661 661
662 status = usb_allocmem(&sc->sc_bus, size, 0, dma); 662 status = usb_allocmem(&sc->sc_bus, size, 0, dma);
663#ifdef __NetBSD__ 663#ifdef __NetBSD__
664 if (status == USBD_NOMEM) 664 if (status == USBD_NOMEM)
665 status = usb_reserve_allocm(&sc->sc_dma_reserve, dma, size); 665 status = usb_reserve_allocm(&sc->sc_dma_reserve, dma, size);
666#endif 666#endif
667 return status; 667 return status;
668} 668}
669 669
670void 670void
671uhci_freem(struct usbd_bus *bus, usb_dma_t *dma) 671uhci_freem(struct usbd_bus *bus, usb_dma_t *dma)
672{ 672{
673#ifdef __NetBSD__ 673#ifdef __NetBSD__
674 if (dma->block->flags & USB_DMA_RESERVE) { 674 if (dma->block->flags & USB_DMA_RESERVE) {
675 usb_reserve_freem(&((struct uhci_softc *)bus)->sc_dma_reserve, 675 usb_reserve_freem(&((struct uhci_softc *)bus)->sc_dma_reserve,
676 dma); 676 dma);
677 return; 677 return;
678 } 678 }
679#endif 679#endif
680 usb_freemem(&((struct uhci_softc *)bus)->sc_bus, dma); 680 usb_freemem(&((struct uhci_softc *)bus)->sc_bus, dma);
681} 681}
682 682
683usbd_xfer_handle 683usbd_xfer_handle
684uhci_allocx(struct usbd_bus *bus) 684uhci_allocx(struct usbd_bus *bus)
685{ 685{
686 struct uhci_softc *sc = bus->hci_private; 686 struct uhci_softc *sc = bus->hci_private;
687 usbd_xfer_handle xfer; 687 usbd_xfer_handle xfer;
688 688
689 xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers); 689 xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers);
690 if (xfer != NULL) { 690 if (xfer != NULL) {
691 SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, next); 691 SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, next);
692#ifdef DIAGNOSTIC 692#ifdef DIAGNOSTIC
693 if (xfer->busy_free != XFER_FREE) { 693 if (xfer->busy_free != XFER_FREE) {
694 printf("uhci_allocx: xfer=%p not free, 0x%08x\n", xfer, 694 printf("uhci_allocx: xfer=%p not free, 0x%08x\n", xfer,
695 xfer->busy_free); 695 xfer->busy_free);
696 } 696 }
697#endif 697#endif
698 } else { 698 } else {
699 xfer = malloc(sizeof(struct uhci_xfer), M_USB, M_NOWAIT); 699 xfer = malloc(sizeof(struct uhci_xfer), M_USB, M_NOWAIT);
700 } 700 }
701 if (xfer != NULL) { 701 if (xfer != NULL) {
702 memset(xfer, 0, sizeof (struct uhci_xfer)); 702 memset(xfer, 0, sizeof (struct uhci_xfer));
703 UXFER(xfer)->iinfo.sc = sc; 703 UXFER(xfer)->iinfo.sc = sc;
704#ifdef DIAGNOSTIC 704#ifdef DIAGNOSTIC
705 UXFER(xfer)->iinfo.isdone = 1; 705 UXFER(xfer)->iinfo.isdone = 1;
706 xfer->busy_free = XFER_BUSY; 706 xfer->busy_free = XFER_BUSY;
707#endif 707#endif
708 } 708 }
709 return (xfer); 709 return (xfer);
710} 710}
711 711
712void 712void
713uhci_freex(struct usbd_bus *bus, usbd_xfer_handle xfer) 713uhci_freex(struct usbd_bus *bus, usbd_xfer_handle xfer)
714{ 714{
715 struct uhci_softc *sc = bus->hci_private; 715 struct uhci_softc *sc = bus->hci_private;
716 716
717#ifdef DIAGNOSTIC 717#ifdef DIAGNOSTIC
718 if (xfer->busy_free != XFER_BUSY) { 718 if (xfer->busy_free != XFER_BUSY) {
719 printf("uhci_freex: xfer=%p not busy, 0x%08x\n", xfer, 719 printf("uhci_freex: xfer=%p not busy, 0x%08x\n", xfer,
720 xfer->busy_free); 720 xfer->busy_free);
721 } 721 }
722 xfer->busy_free = XFER_FREE; 722 xfer->busy_free = XFER_FREE;
723 if (!UXFER(xfer)->iinfo.isdone) { 723 if (!UXFER(xfer)->iinfo.isdone) {
724 printf("uhci_freex: !isdone\n"); 724 printf("uhci_freex: !isdone\n");
725 } 725 }
726#endif 726#endif
727 SIMPLEQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next); 727 SIMPLEQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next);
728} 728}
729 729
730/* 730/*
731 * Handle suspend/resume. 731 * Handle suspend/resume.
732 * 732 *
733 * We need to switch to polling mode here, because this routine is 733 * We need to switch to polling mode here, because this routine is
734 * called from an interrupt context. This is all right since we 734 * called from an interrupt context. This is all right since we
735 * are almost suspended anyway. 735 * are almost suspended anyway.
736 */ 736 */
737bool 737bool
738uhci_resume(device_t dv PMF_FN_ARGS) 738uhci_resume(device_t dv PMF_FN_ARGS)
739{ 739{
740 uhci_softc_t *sc = device_private(dv); 740 uhci_softc_t *sc = device_private(dv);
741 int cmd; 741 int cmd;
742 int s; 742 int s;
743 743
744 s = splhardusb(); 744 s = splhardusb();
745 745
746 cmd = UREAD2(sc, UHCI_CMD); 746 cmd = UREAD2(sc, UHCI_CMD);
747 sc->sc_bus.use_polling++; 747 sc->sc_bus.use_polling++;
748 UWRITE2(sc, UHCI_INTR, 0); 748 UWRITE2(sc, UHCI_INTR, 0);
749 uhci_globalreset(sc); 749 uhci_globalreset(sc);
750 uhci_reset(sc); 750 uhci_reset(sc);
751 if (cmd & UHCI_CMD_RS) 751 if (cmd & UHCI_CMD_RS)
752 uhci_run(sc, 0); 752 uhci_run(sc, 0);
753 753
754 /* restore saved state */ 754 /* restore saved state */
755 UWRITE4(sc, UHCI_FLBASEADDR, DMAADDR(&sc->sc_dma, 0)); 755 UWRITE4(sc, UHCI_FLBASEADDR, DMAADDR(&sc->sc_dma, 0));
756 UWRITE2(sc, UHCI_FRNUM, sc->sc_saved_frnum); 756 UWRITE2(sc, UHCI_FRNUM, sc->sc_saved_frnum);
757 UWRITE1(sc, UHCI_SOF, sc->sc_saved_sof); 757 UWRITE1(sc, UHCI_SOF, sc->sc_saved_sof);
758 758
759 UHCICMD(sc, cmd | UHCI_CMD_FGR); /* force resume */ 759 UHCICMD(sc, cmd | UHCI_CMD_FGR); /* force resume */
760 usb_delay_ms(&sc->sc_bus, USB_RESUME_DELAY); 760 usb_delay_ms(&sc->sc_bus, USB_RESUME_DELAY);
761 UHCICMD(sc, cmd & ~UHCI_CMD_EGSM); /* back to normal */ 761 UHCICMD(sc, cmd & ~UHCI_CMD_EGSM); /* back to normal */
762 UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE | 762 UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE |
763 UHCI_INTR_RIE | UHCI_INTR_IOCE | UHCI_INTR_SPIE); 763 UHCI_INTR_RIE | UHCI_INTR_IOCE | UHCI_INTR_SPIE);
764 UHCICMD(sc, UHCI_CMD_MAXP); 764 UHCICMD(sc, UHCI_CMD_MAXP);
765 uhci_run(sc, 1); /* and start traffic again */ 765 uhci_run(sc, 1); /* and start traffic again */
766 usb_delay_ms(&sc->sc_bus, USB_RESUME_RECOVERY); 766 usb_delay_ms(&sc->sc_bus, USB_RESUME_RECOVERY);
767 sc->sc_bus.use_polling--; 767 sc->sc_bus.use_polling--;
768 if (sc->sc_intr_xfer != NULL) 768 if (sc->sc_intr_xfer != NULL)
769 usb_callout(sc->sc_poll_handle, sc->sc_ival, uhci_poll_hub, 769 usb_callout(sc->sc_poll_handle, sc->sc_ival, uhci_poll_hub,
770 sc->sc_intr_xfer); 770 sc->sc_intr_xfer);
771#ifdef UHCI_DEBUG 771#ifdef UHCI_DEBUG
772 if (uhcidebug > 2) 772 if (uhcidebug > 2)
773 uhci_dumpregs(sc); 773 uhci_dumpregs(sc);
774#endif 774#endif
775 775
776 sc->sc_suspend = PWR_RESUME; 776 sc->sc_suspend = PWR_RESUME;
777 splx(s); 777 splx(s);
778 778
779 return true; 779 return true;
780} 780}
781 781
782bool 782bool
783uhci_suspend(device_t dv PMF_FN_ARGS) 783uhci_suspend(device_t dv PMF_FN_ARGS)
784{ 784{
785 uhci_softc_t *sc = device_private(dv); 785 uhci_softc_t *sc = device_private(dv);
786 int cmd; 786 int cmd;
787 int s; 787 int s;
788 788
789 s = splhardusb(); 789 s = splhardusb();
790 790
791 cmd = UREAD2(sc, UHCI_CMD); 791 cmd = UREAD2(sc, UHCI_CMD);
792 792
793#ifdef UHCI_DEBUG 793#ifdef UHCI_DEBUG
794 if (uhcidebug > 2) 794 if (uhcidebug > 2)
795 uhci_dumpregs(sc); 795 uhci_dumpregs(sc);
796#endif 796#endif
797 if (sc->sc_intr_xfer != NULL) 797 if (sc->sc_intr_xfer != NULL)
798 usb_uncallout(sc->sc_poll_handle, uhci_poll_hub, 798 usb_uncallout(sc->sc_poll_handle, uhci_poll_hub,
799 sc->sc_intr_xfer); 799 sc->sc_intr_xfer);
800 sc->sc_suspend = PWR_SUSPEND; 800 sc->sc_suspend = PWR_SUSPEND;
801 sc->sc_bus.use_polling++; 801 sc->sc_bus.use_polling++;
802 802
803 uhci_run(sc, 0); /* stop the controller */ 803 uhci_run(sc, 0); /* stop the controller */
804 cmd &= ~UHCI_CMD_RS; 804 cmd &= ~UHCI_CMD_RS;
805 805
806 /* save some state if BIOS doesn't */ 806 /* save some state if BIOS doesn't */
807 sc->sc_saved_frnum = UREAD2(sc, UHCI_FRNUM); 807 sc->sc_saved_frnum = UREAD2(sc, UHCI_FRNUM);
808 sc->sc_saved_sof = UREAD1(sc, UHCI_SOF); 808 sc->sc_saved_sof = UREAD1(sc, UHCI_SOF);
809 809
810 UWRITE2(sc, UHCI_INTR, 0); /* disable intrs */ 810 UWRITE2(sc, UHCI_INTR, 0); /* disable intrs */
811 811
812 UHCICMD(sc, cmd | UHCI_CMD_EGSM); /* enter suspend */ 812 UHCICMD(sc, cmd | UHCI_CMD_EGSM); /* enter suspend */
813 usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT); 813 usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT);
814 sc->sc_bus.use_polling--; 814 sc->sc_bus.use_polling--;
815 815
816 splx(s); 816 splx(s);
817 817
818 return true; 818 return true;
819} 819}
820 820
821#ifdef UHCI_DEBUG 821#ifdef UHCI_DEBUG
822Static void 822Static void
823uhci_dumpregs(uhci_softc_t *sc) 823uhci_dumpregs(uhci_softc_t *sc)
824{ 824{
825 DPRINTFN(-1,("%s regs: cmd=%04x, sts=%04x, intr=%04x, frnum=%04x, " 825 DPRINTFN(-1,("%s regs: cmd=%04x, sts=%04x, intr=%04x, frnum=%04x, "
826 "flbase=%08x, sof=%04x, portsc1=%04x, portsc2=%04x\n", 826 "flbase=%08x, sof=%04x, portsc1=%04x, portsc2=%04x\n",
827 device_xname(sc->sc_dev), 827 device_xname(sc->sc_dev),
828 UREAD2(sc, UHCI_CMD), 828 UREAD2(sc, UHCI_CMD),
829 UREAD2(sc, UHCI_STS), 829 UREAD2(sc, UHCI_STS),
830 UREAD2(sc, UHCI_INTR), 830 UREAD2(sc, UHCI_INTR),
831 UREAD2(sc, UHCI_FRNUM), 831 UREAD2(sc, UHCI_FRNUM),
832 UREAD4(sc, UHCI_FLBASEADDR), 832 UREAD4(sc, UHCI_FLBASEADDR),
833 UREAD1(sc, UHCI_SOF), 833 UREAD1(sc, UHCI_SOF),
834 UREAD2(sc, UHCI_PORTSC1), 834 UREAD2(sc, UHCI_PORTSC1),
835 UREAD2(sc, UHCI_PORTSC2))); 835 UREAD2(sc, UHCI_PORTSC2)));
836} 836}
837 837
838void 838void
839uhci_dump_td(uhci_soft_td_t *p) 839uhci_dump_td(uhci_soft_td_t *p)
840{ 840{
841 char sbuf[128], sbuf2[128]; 841 char sbuf[128], sbuf2[128];
842 842
843  843
844 usb_syncmem(&p->dma, p->offs, sizeof(p->td), 844 usb_syncmem(&p->dma, p->offs, sizeof(p->td),
845 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 845 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
846 DPRINTFN(-1,("TD(%p) at %08lx = link=0x%08lx status=0x%08lx " 846 DPRINTFN(-1,("TD(%p) at %08lx = link=0x%08lx status=0x%08lx "
847 "token=0x%08lx buffer=0x%08lx\n", 847 "token=0x%08lx buffer=0x%08lx\n",
848 p, (long)p->physaddr, 848 p, (long)p->physaddr,
849 (long)le32toh(p->td.td_link), 849 (long)le32toh(p->td.td_link),
850 (long)le32toh(p->td.td_status), 850 (long)le32toh(p->td.td_status),
851 (long)le32toh(p->td.td_token), 851 (long)le32toh(p->td.td_token),
852 (long)le32toh(p->td.td_buffer))); 852 (long)le32toh(p->td.td_buffer)));
853 853
854 snprintb(sbuf, sizeof(sbuf), "\20\1T\2Q\3VF", 854 snprintb(sbuf, sizeof(sbuf), "\20\1T\2Q\3VF",
855 (u_int32_t)le32toh(p->td.td_link)); 855 (u_int32_t)le32toh(p->td.td_link));
856 snprintb(sbuf2, sizeof(sbuf2), 856 snprintb(sbuf2, sizeof(sbuf2),
857 "\20\22BITSTUFF\23CRCTO\24NAK\25BABBLE\26DBUFFER\27" 857 "\20\22BITSTUFF\23CRCTO\24NAK\25BABBLE\26DBUFFER\27"
858 "STALLED\30ACTIVE\31IOC\32ISO\33LS\36SPD", 858 "STALLED\30ACTIVE\31IOC\32ISO\33LS\36SPD",
859 (u_int32_t)le32toh(p->td.td_status)); 859 (u_int32_t)le32toh(p->td.td_status));
860 860
861 DPRINTFN(-1,(" %s %s,errcnt=%d,actlen=%d pid=%02x,addr=%d,endpt=%d," 861 DPRINTFN(-1,(" %s %s,errcnt=%d,actlen=%d pid=%02x,addr=%d,endpt=%d,"
862 "D=%d,maxlen=%d\n", sbuf, sbuf2, 862 "D=%d,maxlen=%d\n", sbuf, sbuf2,
863 UHCI_TD_GET_ERRCNT(le32toh(p->td.td_status)), 863 UHCI_TD_GET_ERRCNT(le32toh(p->td.td_status)),
864 UHCI_TD_GET_ACTLEN(le32toh(p->td.td_status)), 864 UHCI_TD_GET_ACTLEN(le32toh(p->td.td_status)),
865 UHCI_TD_GET_PID(le32toh(p->td.td_token)), 865 UHCI_TD_GET_PID(le32toh(p->td.td_token)),
866 UHCI_TD_GET_DEVADDR(le32toh(p->td.td_token)), 866 UHCI_TD_GET_DEVADDR(le32toh(p->td.td_token)),
867 UHCI_TD_GET_ENDPT(le32toh(p->td.td_token)), 867 UHCI_TD_GET_ENDPT(le32toh(p->td.td_token)),
868 UHCI_TD_GET_DT(le32toh(p->td.td_token)), 868 UHCI_TD_GET_DT(le32toh(p->td.td_token)),
869 UHCI_TD_GET_MAXLEN(le32toh(p->td.td_token)))); 869 UHCI_TD_GET_MAXLEN(le32toh(p->td.td_token))));
870 usb_syncmem(&p->dma, p->offs, sizeof(p->td), 870 usb_syncmem(&p->dma, p->offs, sizeof(p->td),
871 BUS_DMASYNC_PREREAD); 871 BUS_DMASYNC_PREREAD);
872} 872}
873 873
874void 874void
875uhci_dump_qh(uhci_soft_qh_t *sqh) 875uhci_dump_qh(uhci_soft_qh_t *sqh)
876{ 876{
877 usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), 877 usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh),
878 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 878 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
879 DPRINTFN(-1,("QH(%p) at %08x: hlink=%08x elink=%08x\n", sqh, 879 DPRINTFN(-1,("QH(%p) at %08x: hlink=%08x elink=%08x\n", sqh,
880 (int)sqh->physaddr, le32toh(sqh->qh.qh_hlink), 880 (int)sqh->physaddr, le32toh(sqh->qh.qh_hlink),
881 le32toh(sqh->qh.qh_elink))); 881 le32toh(sqh->qh.qh_elink)));
882 usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), BUS_DMASYNC_PREREAD); 882 usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), BUS_DMASYNC_PREREAD);
883} 883}
884 884
885 885
886#if 1 886#if 1
887void 887void
888uhci_dump(void) 888uhci_dump(void)
889{ 889{
890 uhci_dump_all(thesc); 890 uhci_dump_all(thesc);
891} 891}
892#endif 892#endif
893 893
894void 894void
895uhci_dump_all(uhci_softc_t *sc) 895uhci_dump_all(uhci_softc_t *sc)
896{ 896{
897 uhci_dumpregs(sc); 897 uhci_dumpregs(sc);
898 printf("intrs=%d\n", sc->sc_bus.no_intrs); 898 printf("intrs=%d\n", sc->sc_bus.no_intrs);
899 /*printf("framelist[i].link = %08x\n", sc->sc_framelist[0].link);*/ 899 /*printf("framelist[i].link = %08x\n", sc->sc_framelist[0].link);*/
900 uhci_dump_qh(sc->sc_lctl_start); 900 uhci_dump_qh(sc->sc_lctl_start);
901} 901}
902 902
903 903
904void 904void
905uhci_dump_qhs(uhci_soft_qh_t *sqh) 905uhci_dump_qhs(uhci_soft_qh_t *sqh)
906{ 906{
907 uhci_dump_qh(sqh); 907 uhci_dump_qh(sqh);
908 908
909 /* uhci_dump_qhs displays all the QHs and TDs from the given QH onwards 909 /* uhci_dump_qhs displays all the QHs and TDs from the given QH onwards
910 * Traverses sideways first, then down. 910 * Traverses sideways first, then down.
911 * 911 *
912 * QH1 912 * QH1
913 * QH2 913 * QH2
914 * No QH 914 * No QH
915 * TD2.1 915 * TD2.1
916 * TD2.2 916 * TD2.2
917 * TD1.1 917 * TD1.1
918 * etc. 918 * etc.
919 * 919 *
920 * TD2.x being the TDs queued at QH2 and QH1 being referenced from QH1. 920 * TD2.x being the TDs queued at QH2 and QH1 being referenced from QH1.
921 */ 921 */
922 922
923 923
924 usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), 924 usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh),
925 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 925 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
926 if (sqh->hlink != NULL && !(le32toh(sqh->qh.qh_hlink) & UHCI_PTR_T)) 926 if (sqh->hlink != NULL && !(le32toh(sqh->qh.qh_hlink) & UHCI_PTR_T))
927 uhci_dump_qhs(sqh->hlink); 927 uhci_dump_qhs(sqh->hlink);
928 else 928 else
929 DPRINTF(("No QH\n")); 929 DPRINTF(("No QH\n"));
930 usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), BUS_DMASYNC_PREREAD); 930 usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), BUS_DMASYNC_PREREAD);
931 931
932 if (sqh->elink != NULL && !(le32toh(sqh->qh.qh_elink) & UHCI_PTR_T)) 932 if (sqh->elink != NULL && !(le32toh(sqh->qh.qh_elink) & UHCI_PTR_T))
933 uhci_dump_tds(sqh->elink); 933 uhci_dump_tds(sqh->elink);
934 else 934 else
935 DPRINTF(("No TD\n")); 935 DPRINTF(("No TD\n"));
936} 936}
937 937
938void 938void
939uhci_dump_tds(uhci_soft_td_t *std) 939uhci_dump_tds(uhci_soft_td_t *std)
940{ 940{
941 uhci_soft_td_t *td; 941 uhci_soft_td_t *td;
942 int stop; 942 int stop;
943 943
944 for(td = std; td != NULL; td = td->link.std) { 944 for(td = std; td != NULL; td = td->link.std) {
945 uhci_dump_td(td); 945 uhci_dump_td(td);
946 946
947 /* Check whether the link pointer in this TD marks 947 /* Check whether the link pointer in this TD marks
948 * the link pointer as end of queue. This avoids 948 * the link pointer as end of queue. This avoids
949 * printing the free list in case the queue/TD has 949 * printing the free list in case the queue/TD has
950 * already been moved there (seatbelt). 950 * already been moved there (seatbelt).
951 */ 951 */
952 usb_syncmem(&td->dma, td->offs + offsetof(uhci_td_t, td_link), 952 usb_syncmem(&td->dma, td->offs + offsetof(uhci_td_t, td_link),
953 sizeof(td->td.td_link), 953 sizeof(td->td.td_link),
954 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 954 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
955 stop = (le32toh(td->td.td_link) & UHCI_PTR_T || 955 stop = (le32toh(td->td.td_link) & UHCI_PTR_T ||
956 le32toh(td->td.td_link) == 0); 956 le32toh(td->td.td_link) == 0);
957 usb_syncmem(&td->dma, td->offs + offsetof(uhci_td_t, td_link), 957 usb_syncmem(&td->dma, td->offs + offsetof(uhci_td_t, td_link),
958 sizeof(td->td.td_link), BUS_DMASYNC_PREREAD); 958 sizeof(td->td.td_link), BUS_DMASYNC_PREREAD);
959 if (stop) 959 if (stop)
960 break; 960 break;
961 } 961 }
962} 962}
963 963
964Static void 964Static void
965uhci_dump_ii(uhci_intr_info_t *ii) 965uhci_dump_ii(uhci_intr_info_t *ii)
966{ 966{
967 usbd_pipe_handle pipe; 967 usbd_pipe_handle pipe;
968 usb_endpoint_descriptor_t *ed; 968 usb_endpoint_descriptor_t *ed;
969 usbd_device_handle dev; 969 usbd_device_handle dev;
970 970
971#ifdef DIAGNOSTIC 971#ifdef DIAGNOSTIC
972#define DONE ii->isdone 972#define DONE ii->isdone
973#else 973#else
974#define DONE 0 974#define DONE 0
975#endif 975#endif
976 if (ii == NULL) { 976 if (ii == NULL) {
977 printf("ii NULL\n"); 977 printf("ii NULL\n");
978 return; 978 return;
979 } 979 }
980 if (ii->xfer == NULL) { 980 if (ii->xfer == NULL) {
981 printf("ii %p: done=%d xfer=NULL\n", 981 printf("ii %p: done=%d xfer=NULL\n",
982 ii, DONE); 982 ii, DONE);
983 return; 983 return;
984 } 984 }
985 pipe = ii->xfer->pipe; 985 pipe = ii->xfer->pipe;
986 if (pipe == NULL) { 986 if (pipe == NULL) {
987 printf("ii %p: done=%d xfer=%p pipe=NULL\n", 987 printf("ii %p: done=%d xfer=%p pipe=NULL\n",
988 ii, DONE, ii->xfer); 988 ii, DONE, ii->xfer);
989 return; 989 return;
990 } 990 }
991 if (pipe->endpoint == NULL) { 991 if (pipe->endpoint == NULL) {
992 printf("ii %p: done=%d xfer=%p pipe=%p pipe->endpoint=NULL\n", 992 printf("ii %p: done=%d xfer=%p pipe=%p pipe->endpoint=NULL\n",
993 ii, DONE, ii->xfer, pipe); 993 ii, DONE, ii->xfer, pipe);
994 return; 994 return;
995 } 995 }
996 if (pipe->device == NULL) { 996 if (pipe->device == NULL) {
997 printf("ii %p: done=%d xfer=%p pipe=%p pipe->device=NULL\n", 997 printf("ii %p: done=%d xfer=%p pipe=%p pipe->device=NULL\n",
998 ii, DONE, ii->xfer, pipe); 998 ii, DONE, ii->xfer, pipe);
999 return; 999 return;
1000 } 1000 }
1001 ed = pipe->endpoint->edesc; 1001 ed = pipe->endpoint->edesc;
1002 dev = pipe->device; 1002 dev = pipe->device;
1003 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", 1003 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",
1004 ii, DONE, ii->xfer, dev, 1004 ii, DONE, ii->xfer, dev,
1005 UGETW(dev->ddesc.idVendor), 1005 UGETW(dev->ddesc.idVendor),
1006 UGETW(dev->ddesc.idProduct), 1006 UGETW(dev->ddesc.idProduct),
1007 dev->address, pipe, 1007 dev->address, pipe,
1008 ed->bEndpointAddress, ed->bmAttributes); 1008 ed->bEndpointAddress, ed->bmAttributes);
1009#undef DONE 1009#undef DONE
1010} 1010}
1011 1011
1012void uhci_dump_iis(struct uhci_softc *sc); 1012void uhci_dump_iis(struct uhci_softc *sc);
1013void 1013void
1014uhci_dump_iis(struct uhci_softc *sc) 1014uhci_dump_iis(struct uhci_softc *sc)
1015{ 1015{
1016 uhci_intr_info_t *ii; 1016 uhci_intr_info_t *ii;
1017 1017
1018 printf("intr_info list:\n"); 1018 printf("intr_info list:\n");
1019 for (ii = LIST_FIRST(&sc->sc_intrhead); ii; ii = LIST_NEXT(ii, list)) 1019 for (ii = LIST_FIRST(&sc->sc_intrhead); ii; ii = LIST_NEXT(ii, list))
1020 uhci_dump_ii(ii); 1020 uhci_dump_ii(ii);
1021} 1021}
1022 1022
1023void iidump(void); 1023void iidump(void);
1024void iidump(void) { uhci_dump_iis(thesc); } 1024void iidump(void) { uhci_dump_iis(thesc); }
1025 1025
1026#endif 1026#endif
1027 1027
1028/* 1028/*
1029 * This routine is executed periodically and simulates interrupts 1029 * This routine is executed periodically and simulates interrupts
1030 * from the root controller interrupt pipe for port status change. 1030 * from the root controller interrupt pipe for port status change.
1031 */ 1031 */
1032void 1032void
1033uhci_poll_hub(void *addr) 1033uhci_poll_hub(void *addr)
1034{ 1034{
1035 usbd_xfer_handle xfer = addr; 1035 usbd_xfer_handle xfer = addr;
1036 usbd_pipe_handle pipe = xfer->pipe; 1036 usbd_pipe_handle pipe = xfer->pipe;
1037 uhci_softc_t *sc; 1037 uhci_softc_t *sc;
1038 int s; 1038 int s;
1039 u_char *p; 1039 u_char *p;
1040 1040
1041 DPRINTFN(20, ("uhci_poll_hub\n")); 1041 DPRINTFN(20, ("uhci_poll_hub\n"));
1042 1042
1043 if (pipe->device == NULL) return; /* device has detached */ 1043 if (__predict_false(pipe->device == NULL || pipe->device->bus == NULL))
 1044 return; /* device has detached */
1044 sc = pipe->device->bus->hci_private; 1045 sc = pipe->device->bus->hci_private;
1045 usb_callout(sc->sc_poll_handle, sc->sc_ival, uhci_poll_hub, xfer); 1046 usb_callout(sc->sc_poll_handle, sc->sc_ival, uhci_poll_hub, xfer);
1046 1047
1047 p = KERNADDR(&xfer->dmabuf, 0); 1048 p = KERNADDR(&xfer->dmabuf, 0);
1048 p[0] = 0; 1049 p[0] = 0;
1049 if (UREAD2(sc, UHCI_PORTSC1) & (UHCI_PORTSC_CSC|UHCI_PORTSC_OCIC)) 1050 if (UREAD2(sc, UHCI_PORTSC1) & (UHCI_PORTSC_CSC|UHCI_PORTSC_OCIC))
1050 p[0] |= 1<<1; 1051 p[0] |= 1<<1;
1051 if (UREAD2(sc, UHCI_PORTSC2) & (UHCI_PORTSC_CSC|UHCI_PORTSC_OCIC)) 1052 if (UREAD2(sc, UHCI_PORTSC2) & (UHCI_PORTSC_CSC|UHCI_PORTSC_OCIC))
1052 p[0] |= 1<<2; 1053 p[0] |= 1<<2;
1053 if (p[0] == 0) 1054 if (p[0] == 0)
1054 /* No change, try again in a while */ 1055 /* No change, try again in a while */
1055 return; 1056 return;
1056 1057
1057 xfer->actlen = 1; 1058 xfer->actlen = 1;
1058 xfer->status = USBD_NORMAL_COMPLETION; 1059 xfer->status = USBD_NORMAL_COMPLETION;
1059 s = splusb(); 1060 s = splusb();
1060 xfer->device->bus->intr_context++; 1061 xfer->device->bus->intr_context++;
1061 usb_transfer_complete(xfer); 1062 usb_transfer_complete(xfer);
1062 xfer->device->bus->intr_context--; 1063 xfer->device->bus->intr_context--;
1063 splx(s); 1064 splx(s);
1064} 1065}
1065 1066
1066void 1067void
1067uhci_root_intr_done(usbd_xfer_handle xfer) 1068uhci_root_intr_done(usbd_xfer_handle xfer)
1068{ 1069{
1069} 1070}
1070 1071
1071void 1072void
1072uhci_root_ctrl_done(usbd_xfer_handle xfer) 1073uhci_root_ctrl_done(usbd_xfer_handle xfer)
1073{ 1074{
1074} 1075}
1075 1076
1076/* 1077/*
1077 * Let the last QH loop back to the high speed control transfer QH. 1078 * Let the last QH loop back to the high speed control transfer QH.
1078 * This is what intel calls "bandwidth reclamation" and improves 1079 * This is what intel calls "bandwidth reclamation" and improves
1079 * USB performance a lot for some devices. 1080 * USB performance a lot for some devices.
1080 * If we are already looping, just count it. 1081 * If we are already looping, just count it.
1081 */ 1082 */
1082void 1083void
1083uhci_add_loop(uhci_softc_t *sc) { 1084uhci_add_loop(uhci_softc_t *sc) {
1084#ifdef UHCI_DEBUG 1085#ifdef UHCI_DEBUG
1085 if (uhcinoloop) 1086 if (uhcinoloop)
1086 return; 1087 return;
1087#endif 1088#endif
1088 if (++sc->sc_loops == 1) { 1089 if (++sc->sc_loops == 1) {
1089 DPRINTFN(5,("uhci_start_loop: add\n")); 1090 DPRINTFN(5,("uhci_start_loop: add\n"));
1090 /* Note, we don't loop back the soft pointer. */ 1091 /* Note, we don't loop back the soft pointer. */
1091 sc->sc_last_qh->qh.qh_hlink = 1092 sc->sc_last_qh->qh.qh_hlink =
1092 htole32(sc->sc_hctl_start->physaddr | UHCI_PTR_QH); 1093 htole32(sc->sc_hctl_start->physaddr | UHCI_PTR_QH);
1093 usb_syncmem(&sc->sc_last_qh->dma, 1094 usb_syncmem(&sc->sc_last_qh->dma,
1094 sc->sc_last_qh->offs + offsetof(uhci_qh_t, qh_hlink), 1095 sc->sc_last_qh->offs + offsetof(uhci_qh_t, qh_hlink),
1095 sizeof(sc->sc_last_qh->qh.qh_hlink), 1096 sizeof(sc->sc_last_qh->qh.qh_hlink),
1096 BUS_DMASYNC_PREWRITE); 1097 BUS_DMASYNC_PREWRITE);
1097 } 1098 }
1098} 1099}
1099 1100
1100void 1101void
1101uhci_rem_loop(uhci_softc_t *sc) { 1102uhci_rem_loop(uhci_softc_t *sc) {
1102#ifdef UHCI_DEBUG 1103#ifdef UHCI_DEBUG
1103 if (uhcinoloop) 1104 if (uhcinoloop)
1104 return; 1105 return;
1105#endif 1106#endif
1106 if (--sc->sc_loops == 0) { 1107 if (--sc->sc_loops == 0) {
1107 DPRINTFN(5,("uhci_end_loop: remove\n")); 1108 DPRINTFN(5,("uhci_end_loop: remove\n"));
1108 sc->sc_last_qh->qh.qh_hlink = htole32(UHCI_PTR_T); 1109 sc->sc_last_qh->qh.qh_hlink = htole32(UHCI_PTR_T);
1109 usb_syncmem(&sc->sc_last_qh->dma, 1110 usb_syncmem(&sc->sc_last_qh->dma,
1110 sc->sc_last_qh->offs + offsetof(uhci_qh_t, qh_hlink), 1111 sc->sc_last_qh->offs + offsetof(uhci_qh_t, qh_hlink),
1111 sizeof(sc->sc_last_qh->qh.qh_hlink), 1112 sizeof(sc->sc_last_qh->qh.qh_hlink),
1112 BUS_DMASYNC_PREWRITE); 1113 BUS_DMASYNC_PREWRITE);
1113 } 1114 }
1114} 1115}
1115 1116
1116/* Add high speed control QH, called at splusb(). */ 1117/* Add high speed control QH, called at splusb(). */
1117void 1118void
1118uhci_add_hs_ctrl(uhci_softc_t *sc, uhci_soft_qh_t *sqh) 1119uhci_add_hs_ctrl(uhci_softc_t *sc, uhci_soft_qh_t *sqh)
1119{ 1120{
1120 uhci_soft_qh_t *eqh; 1121 uhci_soft_qh_t *eqh;
1121 1122
1122 SPLUSBCHECK; 1123 SPLUSBCHECK;
1123 1124
1124 DPRINTFN(10, ("uhci_add_ctrl: sqh=%p\n", sqh)); 1125 DPRINTFN(10, ("uhci_add_ctrl: sqh=%p\n", sqh));
1125 eqh = sc->sc_hctl_end; 1126 eqh = sc->sc_hctl_end;
1126 usb_syncmem(&eqh->dma, eqh->offs + offsetof(uhci_qh_t, qh_hlink), 1127 usb_syncmem(&eqh->dma, eqh->offs + offsetof(uhci_qh_t, qh_hlink),
1127 sizeof(eqh->qh.qh_hlink), 1128 sizeof(eqh->qh.qh_hlink),
1128 BUS_DMASYNC_POSTWRITE); 1129 BUS_DMASYNC_POSTWRITE);
1129 sqh->hlink = eqh->hlink; 1130 sqh->hlink = eqh->hlink;
1130 sqh->qh.qh_hlink = eqh->qh.qh_hlink; 1131 sqh->qh.qh_hlink = eqh->qh.qh_hlink;
1131 usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), 1132 usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh),
1132 BUS_DMASYNC_PREWRITE); 1133 BUS_DMASYNC_PREWRITE);
1133 eqh->hlink = sqh; 1134 eqh->hlink = sqh;
1134 eqh->qh.qh_hlink = htole32(sqh->physaddr | UHCI_PTR_QH); 1135 eqh->qh.qh_hlink = htole32(sqh->physaddr | UHCI_PTR_QH);
1135 sc->sc_hctl_end = sqh; 1136 sc->sc_hctl_end = sqh;
1136 usb_syncmem(&eqh->dma, eqh->offs + offsetof(uhci_qh_t, qh_hlink), 1137 usb_syncmem(&eqh->dma, eqh->offs + offsetof(uhci_qh_t, qh_hlink),
1137 sizeof(eqh->qh.qh_hlink), BUS_DMASYNC_PREWRITE); 1138 sizeof(eqh->qh.qh_hlink), BUS_DMASYNC_PREWRITE);
1138#ifdef UHCI_CTL_LOOP 1139#ifdef UHCI_CTL_LOOP
1139 uhci_add_loop(sc); 1140 uhci_add_loop(sc);
1140#endif 1141#endif
1141} 1142}
1142 1143
1143/* Remove high speed control QH, called at splusb(). */ 1144/* Remove high speed control QH, called at splusb(). */
1144void 1145void
1145uhci_remove_hs_ctrl(uhci_softc_t *sc, uhci_soft_qh_t *sqh) 1146uhci_remove_hs_ctrl(uhci_softc_t *sc, uhci_soft_qh_t *sqh)
1146{ 1147{
1147 uhci_soft_qh_t *pqh; 1148 uhci_soft_qh_t *pqh;
1148 1149
1149 SPLUSBCHECK; 1150 SPLUSBCHECK;
1150 1151
1151 DPRINTFN(10, ("uhci_remove_hs_ctrl: sqh=%p\n", sqh)); 1152 DPRINTFN(10, ("uhci_remove_hs_ctrl: sqh=%p\n", sqh));
1152#ifdef UHCI_CTL_LOOP 1153#ifdef UHCI_CTL_LOOP
1153 uhci_rem_loop(sc); 1154 uhci_rem_loop(sc);
1154#endif 1155#endif
1155 /* 1156 /*
1156 * The T bit should be set in the elink of the QH so that the HC 1157 * The T bit should be set in the elink of the QH so that the HC
1157 * doesn't follow the pointer. This condition may fail if the 1158 * doesn't follow the pointer. This condition may fail if the
1158 * the transferred packet was short so that the QH still points 1159 * the transferred packet was short so that the QH still points
1159 * at the last used TD. 1160 * at the last used TD.
1160 * In this case we set the T bit and wait a little for the HC 1161 * In this case we set the T bit and wait a little for the HC
1161 * to stop looking at the TD. 1162 * to stop looking at the TD.
1162 * Note that if the TD chain is large enough, the controller 1163 * Note that if the TD chain is large enough, the controller
1163 * may still be looking at the chain at the end of this function. 1164 * may still be looking at the chain at the end of this function.
1164 * uhci_free_std_chain() will make sure the controller stops 1165 * uhci_free_std_chain() will make sure the controller stops
1165 * looking at it quickly, but until then we should not change 1166 * looking at it quickly, but until then we should not change
1166 * sqh->hlink. 1167 * sqh->hlink.
1167 */ 1168 */
1168 usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_elink), 1169 usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_elink),
1169 sizeof(sqh->qh.qh_elink), 1170 sizeof(sqh->qh.qh_elink),
1170 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1171 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
1171 if (!(sqh->qh.qh_elink & htole32(UHCI_PTR_T))) { 1172 if (!(sqh->qh.qh_elink & htole32(UHCI_PTR_T))) {
1172 sqh->qh.qh_elink = htole32(UHCI_PTR_T); 1173 sqh->qh.qh_elink = htole32(UHCI_PTR_T);
1173 usb_syncmem(&sqh->dma, 1174 usb_syncmem(&sqh->dma,
1174 sqh->offs + offsetof(uhci_qh_t, qh_elink), 1175 sqh->offs + offsetof(uhci_qh_t, qh_elink),
1175 sizeof(sqh->qh.qh_elink), 1176 sizeof(sqh->qh.qh_elink),
1176 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1177 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
1177 delay(UHCI_QH_REMOVE_DELAY); 1178 delay(UHCI_QH_REMOVE_DELAY);
1178 } 1179 }
1179 1180
1180 pqh = uhci_find_prev_qh(sc->sc_hctl_start, sqh); 1181 pqh = uhci_find_prev_qh(sc->sc_hctl_start, sqh);
1181 usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_hlink), 1182 usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_hlink),
1182 sizeof(sqh->qh.qh_hlink), BUS_DMASYNC_POSTWRITE); 1183 sizeof(sqh->qh.qh_hlink), BUS_DMASYNC_POSTWRITE);
1183 pqh->hlink = sqh->hlink; 1184 pqh->hlink = sqh->hlink;
1184 pqh->qh.qh_hlink = sqh->qh.qh_hlink; 1185 pqh->qh.qh_hlink = sqh->qh.qh_hlink;
1185 usb_syncmem(&pqh->dma, pqh->offs + offsetof(uhci_qh_t, qh_hlink), 1186 usb_syncmem(&pqh->dma, pqh->offs + offsetof(uhci_qh_t, qh_hlink),
1186 sizeof(pqh->qh.qh_hlink), 1187 sizeof(pqh->qh.qh_hlink),
1187 BUS_DMASYNC_PREWRITE); 1188 BUS_DMASYNC_PREWRITE);
1188 delay(UHCI_QH_REMOVE_DELAY); 1189 delay(UHCI_QH_REMOVE_DELAY);
1189 if (sc->sc_hctl_end == sqh) 1190 if (sc->sc_hctl_end == sqh)
1190 sc->sc_hctl_end = pqh; 1191 sc->sc_hctl_end = pqh;
1191} 1192}
1192 1193
1193/* Add low speed control QH, called at splusb(). */ 1194/* Add low speed control QH, called at splusb(). */
1194void 1195void
1195uhci_add_ls_ctrl(uhci_softc_t *sc, uhci_soft_qh_t *sqh) 1196uhci_add_ls_ctrl(uhci_softc_t *sc, uhci_soft_qh_t *sqh)
1196{ 1197{
1197 uhci_soft_qh_t *eqh; 1198 uhci_soft_qh_t *eqh;
1198 1199
1199 SPLUSBCHECK; 1200 SPLUSBCHECK;
1200 1201
1201 DPRINTFN(10, ("uhci_add_ls_ctrl: sqh=%p\n", sqh)); 1202 DPRINTFN(10, ("uhci_add_ls_ctrl: sqh=%p\n", sqh));
1202 eqh = sc->sc_lctl_end; 1203 eqh = sc->sc_lctl_end;
1203 usb_syncmem(&eqh->dma, eqh->offs + offsetof(uhci_qh_t, qh_hlink), 1204 usb_syncmem(&eqh->dma, eqh->offs + offsetof(uhci_qh_t, qh_hlink),
1204 sizeof(eqh->qh.qh_hlink), BUS_DMASYNC_POSTWRITE); 1205 sizeof(eqh->qh.qh_hlink), BUS_DMASYNC_POSTWRITE);
1205 sqh->hlink = eqh->hlink; 1206 sqh->hlink = eqh->hlink;
1206 sqh->qh.qh_hlink = eqh->qh.qh_hlink; 1207 sqh->qh.qh_hlink = eqh->qh.qh_hlink;
1207 usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), 1208 usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh),
1208 BUS_DMASYNC_PREWRITE); 1209 BUS_DMASYNC_PREWRITE);
1209 eqh->hlink = sqh; 1210 eqh->hlink = sqh;
1210 eqh->qh.qh_hlink = htole32(sqh->physaddr | UHCI_PTR_QH); 1211 eqh->qh.qh_hlink = htole32(sqh->physaddr | UHCI_PTR_QH);
1211 usb_syncmem(&eqh->dma, eqh->offs + offsetof(uhci_qh_t, qh_hlink), 1212 usb_syncmem(&eqh->dma, eqh->offs + offsetof(uhci_qh_t, qh_hlink),
1212 sizeof(eqh->qh.qh_hlink), BUS_DMASYNC_PREWRITE); 1213 sizeof(eqh->qh.qh_hlink), BUS_DMASYNC_PREWRITE);
1213 sc->sc_lctl_end = sqh; 1214 sc->sc_lctl_end = sqh;
1214} 1215}
1215 1216
1216/* Remove low speed control QH, called at splusb(). */ 1217/* Remove low speed control QH, called at splusb(). */
1217void 1218void
1218uhci_remove_ls_ctrl(uhci_softc_t *sc, uhci_soft_qh_t *sqh) 1219uhci_remove_ls_ctrl(uhci_softc_t *sc, uhci_soft_qh_t *sqh)
1219{ 1220{
1220 uhci_soft_qh_t *pqh; 1221 uhci_soft_qh_t *pqh;
1221 1222
1222 SPLUSBCHECK; 1223 SPLUSBCHECK;
1223 1224
1224 DPRINTFN(10, ("uhci_remove_ls_ctrl: sqh=%p\n", sqh)); 1225 DPRINTFN(10, ("uhci_remove_ls_ctrl: sqh=%p\n", sqh));
1225 /* See comment in uhci_remove_hs_ctrl() */ 1226 /* See comment in uhci_remove_hs_ctrl() */
1226 usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_elink), 1227 usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_elink),
1227 sizeof(sqh->qh.qh_elink), 1228 sizeof(sqh->qh.qh_elink),
1228 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1229 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
1229 if (!(sqh->qh.qh_elink & htole32(UHCI_PTR_T))) { 1230 if (!(sqh->qh.qh_elink & htole32(UHCI_PTR_T))) {
1230 sqh->qh.qh_elink = htole32(UHCI_PTR_T); 1231 sqh->qh.qh_elink = htole32(UHCI_PTR_T);
1231 usb_syncmem(&sqh->dma, 1232 usb_syncmem(&sqh->dma,
1232 sqh->offs + offsetof(uhci_qh_t, qh_elink), 1233 sqh->offs + offsetof(uhci_qh_t, qh_elink),
1233 sizeof(sqh->qh.qh_elink), 1234 sizeof(sqh->qh.qh_elink),
1234 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1235 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
1235 delay(UHCI_QH_REMOVE_DELAY); 1236 delay(UHCI_QH_REMOVE_DELAY);
1236 } 1237 }
1237 pqh = uhci_find_prev_qh(sc->sc_lctl_start, sqh); 1238 pqh = uhci_find_prev_qh(sc->sc_lctl_start, sqh);
1238 usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_hlink), 1239 usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_hlink),
1239 sizeof(sqh->qh.qh_hlink), BUS_DMASYNC_POSTWRITE); 1240 sizeof(sqh->qh.qh_hlink), BUS_DMASYNC_POSTWRITE);
1240 pqh->hlink = sqh->hlink; 1241 pqh->hlink = sqh->hlink;
1241 pqh->qh.qh_hlink = sqh->qh.qh_hlink; 1242 pqh->qh.qh_hlink = sqh->qh.qh_hlink;
1242 usb_syncmem(&pqh->dma, pqh->offs + offsetof(uhci_qh_t, qh_hlink), 1243 usb_syncmem(&pqh->dma, pqh->offs + offsetof(uhci_qh_t, qh_hlink),
1243 sizeof(pqh->qh.qh_hlink), 1244 sizeof(pqh->qh.qh_hlink),
1244 BUS_DMASYNC_PREWRITE); 1245 BUS_DMASYNC_PREWRITE);
1245 delay(UHCI_QH_REMOVE_DELAY); 1246 delay(UHCI_QH_REMOVE_DELAY);
1246 if (sc->sc_lctl_end == sqh) 1247 if (sc->sc_lctl_end == sqh)
1247 sc->sc_lctl_end = pqh; 1248 sc->sc_lctl_end = pqh;
1248} 1249}
1249 1250
1250/* Add bulk QH, called at splusb(). */ 1251/* Add bulk QH, called at splusb(). */
1251void 1252void
1252uhci_add_bulk(uhci_softc_t *sc, uhci_soft_qh_t *sqh) 1253uhci_add_bulk(uhci_softc_t *sc, uhci_soft_qh_t *sqh)
1253{ 1254{
1254 uhci_soft_qh_t *eqh; 1255 uhci_soft_qh_t *eqh;
1255 1256
1256 SPLUSBCHECK; 1257 SPLUSBCHECK;
1257 1258
1258 DPRINTFN(10, ("uhci_add_bulk: sqh=%p\n", sqh)); 1259 DPRINTFN(10, ("uhci_add_bulk: sqh=%p\n", sqh));
1259 eqh = sc->sc_bulk_end; 1260 eqh = sc->sc_bulk_end;
1260 usb_syncmem(&eqh->dma, eqh->offs + offsetof(uhci_qh_t, qh_hlink), 1261 usb_syncmem(&eqh->dma, eqh->offs + offsetof(uhci_qh_t, qh_hlink),
1261 sizeof(eqh->qh.qh_hlink), BUS_DMASYNC_POSTWRITE); 1262 sizeof(eqh->qh.qh_hlink), BUS_DMASYNC_POSTWRITE);
1262 sqh->hlink = eqh->hlink; 1263 sqh->hlink = eqh->hlink;
1263 sqh->qh.qh_hlink = eqh->qh.qh_hlink; 1264 sqh->qh.qh_hlink = eqh->qh.qh_hlink;
1264 usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), 1265 usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh),
1265 BUS_DMASYNC_PREWRITE); 1266 BUS_DMASYNC_PREWRITE);
1266 eqh->hlink = sqh; 1267 eqh->hlink = sqh;
1267 eqh->qh.qh_hlink = htole32(sqh->physaddr | UHCI_PTR_QH); 1268 eqh->qh.qh_hlink = htole32(sqh->physaddr | UHCI_PTR_QH);
1268 usb_syncmem(&eqh->dma, eqh->offs + offsetof(uhci_qh_t, qh_hlink), 1269 usb_syncmem(&eqh->dma, eqh->offs + offsetof(uhci_qh_t, qh_hlink),
1269 sizeof(eqh->qh.qh_hlink), BUS_DMASYNC_PREWRITE); 1270 sizeof(eqh->qh.qh_hlink), BUS_DMASYNC_PREWRITE);
1270 sc->sc_bulk_end = sqh; 1271 sc->sc_bulk_end = sqh;
1271 uhci_add_loop(sc); 1272 uhci_add_loop(sc);
1272} 1273}
1273 1274
1274/* Remove bulk QH, called at splusb(). */ 1275/* Remove bulk QH, called at splusb(). */
1275void 1276void
1276uhci_remove_bulk(uhci_softc_t *sc, uhci_soft_qh_t *sqh) 1277uhci_remove_bulk(uhci_softc_t *sc, uhci_soft_qh_t *sqh)
1277{ 1278{
1278 uhci_soft_qh_t *pqh; 1279 uhci_soft_qh_t *pqh;
1279 1280
1280 SPLUSBCHECK; 1281 SPLUSBCHECK;
1281 1282
1282 DPRINTFN(10, ("uhci_remove_bulk: sqh=%p\n", sqh)); 1283 DPRINTFN(10, ("uhci_remove_bulk: sqh=%p\n", sqh));
1283 uhci_rem_loop(sc); 1284 uhci_rem_loop(sc);
1284 /* See comment in uhci_remove_hs_ctrl() */ 1285 /* See comment in uhci_remove_hs_ctrl() */
1285 usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_elink), 1286 usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_elink),
1286 sizeof(sqh->qh.qh_elink), 1287 sizeof(sqh->qh.qh_elink),
1287 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1288 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
1288 if (!(sqh->qh.qh_elink & htole32(UHCI_PTR_T))) { 1289 if (!(sqh->qh.qh_elink & htole32(UHCI_PTR_T))) {
1289 sqh->qh.qh_elink = htole32(UHCI_PTR_T); 1290 sqh->qh.qh_elink = htole32(UHCI_PTR_T);
1290 usb_syncmem(&sqh->dma, 1291 usb_syncmem(&sqh->dma,
1291 sqh->offs + offsetof(uhci_qh_t, qh_elink), 1292 sqh->offs + offsetof(uhci_qh_t, qh_elink),
1292 sizeof(sqh->qh.qh_elink), 1293 sizeof(sqh->qh.qh_elink),
1293 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1294 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
1294 delay(UHCI_QH_REMOVE_DELAY); 1295 delay(UHCI_QH_REMOVE_DELAY);
1295 } 1296 }
1296 pqh = uhci_find_prev_qh(sc->sc_bulk_start, sqh); 1297 pqh = uhci_find_prev_qh(sc->sc_bulk_start, sqh);
1297 usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_hlink), 1298 usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_hlink),
1298 sizeof(sqh->qh.qh_hlink), BUS_DMASYNC_POSTWRITE); 1299 sizeof(sqh->qh.qh_hlink), BUS_DMASYNC_POSTWRITE);
1299 pqh->hlink = sqh->hlink; 1300 pqh->hlink = sqh->hlink;
1300 pqh->qh.qh_hlink = sqh->qh.qh_hlink; 1301 pqh->qh.qh_hlink = sqh->qh.qh_hlink;
1301 usb_syncmem(&pqh->dma, pqh->offs + offsetof(uhci_qh_t, qh_hlink), 1302 usb_syncmem(&pqh->dma, pqh->offs + offsetof(uhci_qh_t, qh_hlink),
1302 sizeof(pqh->qh.qh_hlink), BUS_DMASYNC_PREWRITE); 1303 sizeof(pqh->qh.qh_hlink), BUS_DMASYNC_PREWRITE);
1303 delay(UHCI_QH_REMOVE_DELAY); 1304 delay(UHCI_QH_REMOVE_DELAY);
1304 if (sc->sc_bulk_end == sqh) 1305 if (sc->sc_bulk_end == sqh)
1305 sc->sc_bulk_end = pqh; 1306 sc->sc_bulk_end = pqh;
1306} 1307}
1307 1308
1308Static int uhci_intr1(uhci_softc_t *); 1309Static int uhci_intr1(uhci_softc_t *);
1309 1310
1310int 1311int
1311uhci_intr(void *arg) 1312uhci_intr(void *arg)
1312{ 1313{
1313 uhci_softc_t *sc = arg; 1314 uhci_softc_t *sc = arg;
1314 1315
1315 if (sc->sc_dying || !device_has_power(sc->sc_dev)) 1316 if (sc->sc_dying || !device_has_power(sc->sc_dev))
1316 return (0); 1317 return (0);
1317 1318
1318 if (sc->sc_bus.use_polling || UREAD2(sc, UHCI_INTR) == 0) { 1319 if (sc->sc_bus.use_polling || UREAD2(sc, UHCI_INTR) == 0) {
1319#ifdef DIAGNOSTIC 1320#ifdef DIAGNOSTIC
1320 DPRINTFN(16, ("uhci_intr: ignored interrupt while polling\n")); 1321 DPRINTFN(16, ("uhci_intr: ignored interrupt while polling\n"));
1321#endif 1322#endif
1322 return (0); 1323 return (0);
1323 } 1324 }
1324 1325
1325 return (uhci_intr1(sc)); 1326 return (uhci_intr1(sc));
1326} 1327}
1327 1328
1328int 1329int
1329uhci_intr1(uhci_softc_t *sc) 1330uhci_intr1(uhci_softc_t *sc)
1330{ 1331{
1331 int status; 1332 int status;
1332 int ack; 1333 int ack;
1333 1334
1334#ifdef UHCI_DEBUG 1335#ifdef UHCI_DEBUG
1335 if (uhcidebug > 15) { 1336 if (uhcidebug > 15) {
1336 DPRINTF(("%s: uhci_intr1\n", device_xname(sc->sc_dev))); 1337 DPRINTF(("%s: uhci_intr1\n", device_xname(sc->sc_dev)));
1337 uhci_dumpregs(sc); 1338 uhci_dumpregs(sc);
1338 } 1339 }
1339#endif 1340#endif
1340 1341
1341 status = UREAD2(sc, UHCI_STS) & UHCI_STS_ALLINTRS; 1342 status = UREAD2(sc, UHCI_STS) & UHCI_STS_ALLINTRS;
1342 if (status == 0) /* The interrupt was not for us. */ 1343 if (status == 0) /* The interrupt was not for us. */
1343 return (0); 1344 return (0);
1344 1345
1345 if (sc->sc_suspend != PWR_RESUME) { 1346 if (sc->sc_suspend != PWR_RESUME) {
1346#ifdef DIAGNOSTIC 1347#ifdef DIAGNOSTIC
1347 printf("%s: interrupt while not operating ignored\n", 1348 printf("%s: interrupt while not operating ignored\n",
1348 device_xname(sc->sc_dev)); 1349 device_xname(sc->sc_dev));
1349#endif 1350#endif
1350 UWRITE2(sc, UHCI_STS, status); /* acknowledge the ints */ 1351 UWRITE2(sc, UHCI_STS, status); /* acknowledge the ints */
1351 return (0); 1352 return (0);
1352 } 1353 }
1353 1354
1354 ack = 0; 1355 ack = 0;
1355 if (status & UHCI_STS_USBINT) 1356 if (status & UHCI_STS_USBINT)
1356 ack |= UHCI_STS_USBINT; 1357 ack |= UHCI_STS_USBINT;
1357 if (status & UHCI_STS_USBEI) 1358 if (status & UHCI_STS_USBEI)
1358 ack |= UHCI_STS_USBEI; 1359 ack |= UHCI_STS_USBEI;
1359 if (status & UHCI_STS_RD) { 1360 if (status & UHCI_STS_RD) {
1360 ack |= UHCI_STS_RD; 1361 ack |= UHCI_STS_RD;
1361#ifdef UHCI_DEBUG 1362#ifdef UHCI_DEBUG
1362 printf("%s: resume detect\n", device_xname(sc->sc_dev)); 1363 printf("%s: resume detect\n", device_xname(sc->sc_dev));
1363#endif 1364#endif
1364 } 1365 }
1365 if (status & UHCI_STS_HSE) { 1366 if (status & UHCI_STS_HSE) {
1366 ack |= UHCI_STS_HSE; 1367 ack |= UHCI_STS_HSE;
1367 printf("%s: host system error\n", device_xname(sc->sc_dev)); 1368 printf("%s: host system error\n", device_xname(sc->sc_dev));
1368 } 1369 }
1369 if (status & UHCI_STS_HCPE) { 1370 if (status & UHCI_STS_HCPE) {
1370 ack |= UHCI_STS_HCPE; 1371 ack |= UHCI_STS_HCPE;
1371 printf("%s: host controller process error\n", 1372 printf("%s: host controller process error\n",
1372 device_xname(sc->sc_dev)); 1373 device_xname(sc->sc_dev));
1373 } 1374 }
1374 if (status & UHCI_STS_HCH) { 1375 if (status & UHCI_STS_HCH) {
1375 /* no acknowledge needed */ 1376 /* no acknowledge needed */
1376 if (!sc->sc_dying) { 1377 if (!sc->sc_dying) {
1377 printf("%s: host controller halted\n", 1378 printf("%s: host controller halted\n",
1378 device_xname(sc->sc_dev)); 1379 device_xname(sc->sc_dev));
1379#ifdef UHCI_DEBUG 1380#ifdef UHCI_DEBUG
1380 uhci_dump_all(sc); 1381 uhci_dump_all(sc);
1381#endif 1382#endif
1382 } 1383 }
1383 sc->sc_dying = 1; 1384 sc->sc_dying = 1;
1384 } 1385 }
1385 1386
1386 if (!ack) 1387 if (!ack)
1387 return (0); /* nothing to acknowledge */ 1388 return (0); /* nothing to acknowledge */
1388 UWRITE2(sc, UHCI_STS, ack); /* acknowledge the ints */ 1389 UWRITE2(sc, UHCI_STS, ack); /* acknowledge the ints */
1389 1390
1390 sc->sc_bus.no_intrs++; 1391 sc->sc_bus.no_intrs++;
1391 usb_schedsoftintr(&sc->sc_bus); 1392 usb_schedsoftintr(&sc->sc_bus);
1392 1393
1393 DPRINTFN(15, ("%s: uhci_intr: exit\n", device_xname(sc->sc_dev))); 1394 DPRINTFN(15, ("%s: uhci_intr: exit\n", device_xname(sc->sc_dev)));
1394 1395
1395 return (1); 1396 return (1);
1396} 1397}
1397 1398
1398void 1399void
1399uhci_softintr(void *v) 1400uhci_softintr(void *v)
1400{ 1401{
1401 struct usbd_bus *bus = v; 1402 struct usbd_bus *bus = v;
1402 uhci_softc_t *sc = bus->hci_private; 1403 uhci_softc_t *sc = bus->hci_private;
1403 uhci_intr_info_t *ii, *nextii; 1404 uhci_intr_info_t *ii, *nextii;
1404 1405
1405 DPRINTFN(10,("%s: uhci_softintr (%d)\n", device_xname(sc->sc_dev), 1406 DPRINTFN(10,("%s: uhci_softintr (%d)\n", device_xname(sc->sc_dev),
1406 sc->sc_bus.intr_context)); 1407 sc->sc_bus.intr_context));
1407 1408
1408 sc->sc_bus.intr_context++; 1409 sc->sc_bus.intr_context++;
1409 1410
1410 /* 1411 /*
1411 * Interrupts on UHCI really suck. When the host controller 1412 * Interrupts on UHCI really suck. When the host controller
1412 * interrupts because a transfer is completed there is no 1413 * interrupts because a transfer is completed there is no
1413 * way of knowing which transfer it was. You can scan down 1414 * way of knowing which transfer it was. You can scan down
1414 * the TDs and QHs of the previous frame to limit the search, 1415 * the TDs and QHs of the previous frame to limit the search,
1415 * but that assumes that the interrupt was not delayed by more 1416 * but that assumes that the interrupt was not delayed by more
1416 * than 1 ms, which may not always be true (e.g. after debug 1417 * than 1 ms, which may not always be true (e.g. after debug
1417 * output on a slow console). 1418 * output on a slow console).
1418 * We scan all interrupt descriptors to see if any have 1419 * We scan all interrupt descriptors to see if any have
1419 * completed. 1420 * completed.
1420 */ 1421 */
1421 for (ii = LIST_FIRST(&sc->sc_intrhead); ii; ii = nextii) { 1422 for (ii = LIST_FIRST(&sc->sc_intrhead); ii; ii = nextii) {
1422 nextii = LIST_NEXT(ii, list); 1423 nextii = LIST_NEXT(ii, list);
1423 uhci_check_intr(sc, ii); 1424 uhci_check_intr(sc, ii);
1424 } 1425 }
1425 1426
1426#ifdef USB_USE_SOFTINTR 1427#ifdef USB_USE_SOFTINTR
1427 if (sc->sc_softwake) { 1428 if (sc->sc_softwake) {
1428 sc->sc_softwake = 0; 1429 sc->sc_softwake = 0;
1429 wakeup(&sc->sc_softwake); 1430 wakeup(&sc->sc_softwake);
1430 } 1431 }
1431#endif /* USB_USE_SOFTINTR */ 1432#endif /* USB_USE_SOFTINTR */
1432 1433
1433 sc->sc_bus.intr_context--; 1434 sc->sc_bus.intr_context--;
1434} 1435}
1435 1436
1436/* Check for an interrupt. */ 1437/* Check for an interrupt. */
1437void 1438void
1438uhci_check_intr(uhci_softc_t *sc, uhci_intr_info_t *ii) 1439uhci_check_intr(uhci_softc_t *sc, uhci_intr_info_t *ii)
1439{ 1440{
1440 uhci_soft_td_t *std, *lstd; 1441 uhci_soft_td_t *std, *lstd;
1441 u_int32_t status; 1442 u_int32_t status;
1442 1443
1443 DPRINTFN(15, ("uhci_check_intr: ii=%p\n", ii)); 1444 DPRINTFN(15, ("uhci_check_intr: ii=%p\n", ii));
1444#ifdef DIAGNOSTIC 1445#ifdef DIAGNOSTIC
1445 if (ii == NULL) { 1446 if (ii == NULL) {
1446 printf("uhci_check_intr: no ii? %p\n", ii); 1447 printf("uhci_check_intr: no ii? %p\n", ii);
1447 return; 1448 return;
1448 } 1449 }
1449#endif 1450#endif
1450 if (ii->xfer->status == USBD_CANCELLED || 1451 if (ii->xfer->status == USBD_CANCELLED ||
1451 ii->xfer->status == USBD_TIMEOUT) { 1452 ii->xfer->status == USBD_TIMEOUT) {
1452 DPRINTF(("uhci_check_intr: aborted xfer=%p\n", ii->xfer)); 1453 DPRINTF(("uhci_check_intr: aborted xfer=%p\n", ii->xfer));
1453 return; 1454 return;
1454 } 1455 }
1455 1456
1456 if (ii->stdstart == NULL) 1457 if (ii->stdstart == NULL)
1457 return; 1458 return;
1458 lstd = ii->stdend; 1459 lstd = ii->stdend;
1459#ifdef DIAGNOSTIC 1460#ifdef DIAGNOSTIC
1460 if (lstd == NULL) { 1461 if (lstd == NULL) {
1461 printf("uhci_check_intr: std==0\n"); 1462 printf("uhci_check_intr: std==0\n");
1462 return; 1463 return;
1463 } 1464 }
1464#endif 1465#endif
1465 /* 1466 /*
1466 * If the last TD is still active we need to check whether there 1467 * If the last TD is still active we need to check whether there
1467 * is an error somewhere in the middle, or whether there was a 1468 * is an error somewhere in the middle, or whether there was a
1468 * short packet (SPD and not ACTIVE). 1469 * short packet (SPD and not ACTIVE).
1469 */ 1470 */
1470 usb_syncmem(&lstd->dma, 1471 usb_syncmem(&lstd->dma,
1471 lstd->offs + offsetof(uhci_td_t, td_status), 1472 lstd->offs + offsetof(uhci_td_t, td_status),
1472 sizeof(lstd->td.td_status), 1473 sizeof(lstd->td.td_status),
1473 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1474 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
1474 if (le32toh(lstd->td.td_status) & UHCI_TD_ACTIVE) { 1475 if (le32toh(lstd->td.td_status) & UHCI_TD_ACTIVE) {
1475 DPRINTFN(12, ("uhci_check_intr: active ii=%p\n", ii)); 1476 DPRINTFN(12, ("uhci_check_intr: active ii=%p\n", ii));
1476 for (std = ii->stdstart; std != lstd; std = std->link.std) { 1477 for (std = ii->stdstart; std != lstd; std = std->link.std) {
1477 usb_syncmem(&std->dma, 1478 usb_syncmem(&std->dma,
1478 std->offs + offsetof(uhci_td_t, td_status), 1479 std->offs + offsetof(uhci_td_t, td_status),
1479 sizeof(std->td.td_status), 1480 sizeof(std->td.td_status),
1480 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1481 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
1481 status = le32toh(std->td.td_status); 1482 status = le32toh(std->td.td_status);
1482 usb_syncmem(&std->dma, 1483 usb_syncmem(&std->dma,
1483 std->offs + offsetof(uhci_td_t, td_status), 1484 std->offs + offsetof(uhci_td_t, td_status),
1484 sizeof(std->td.td_status), BUS_DMASYNC_PREREAD); 1485 sizeof(std->td.td_status), BUS_DMASYNC_PREREAD);
1485 /* If there's an active TD the xfer isn't done. */ 1486 /* If there's an active TD the xfer isn't done. */
1486 if (status & UHCI_TD_ACTIVE) 1487 if (status & UHCI_TD_ACTIVE)
1487 break; 1488 break;
1488 /* Any kind of error makes the xfer done. */ 1489 /* Any kind of error makes the xfer done. */
1489 if (status & UHCI_TD_STALLED) 1490 if (status & UHCI_TD_STALLED)
1490 goto done; 1491 goto done;
1491 /* We want short packets, and it is short: it's done */ 1492 /* We want short packets, and it is short: it's done */
1492 usb_syncmem(&std->dma, 1493 usb_syncmem(&std->dma,
1493 std->offs + offsetof(uhci_td_t, td_token), 1494 std->offs + offsetof(uhci_td_t, td_token),
1494 sizeof(std->td.td_token), 1495 sizeof(std->td.td_token),
1495 BUS_DMASYNC_POSTWRITE); 1496 BUS_DMASYNC_POSTWRITE);
1496 if ((status & UHCI_TD_SPD) && 1497 if ((status & UHCI_TD_SPD) &&
1497 UHCI_TD_GET_ACTLEN(status) < 1498 UHCI_TD_GET_ACTLEN(status) <
1498 UHCI_TD_GET_MAXLEN(le32toh(std->td.td_token))) 1499 UHCI_TD_GET_MAXLEN(le32toh(std->td.td_token)))
1499 goto done; 1500 goto done;
1500 } 1501 }
1501 DPRINTFN(12, ("uhci_check_intr: ii=%p std=%p still active\n", 1502 DPRINTFN(12, ("uhci_check_intr: ii=%p std=%p still active\n",
1502 ii, ii->stdstart)); 1503 ii, ii->stdstart));
1503 usb_syncmem(&lstd->dma, 1504 usb_syncmem(&lstd->dma,
1504 lstd->offs + offsetof(uhci_td_t, td_status), 1505 lstd->offs + offsetof(uhci_td_t, td_status),
1505 sizeof(lstd->td.td_status), 1506 sizeof(lstd->td.td_status),
1506 BUS_DMASYNC_PREREAD); 1507 BUS_DMASYNC_PREREAD);
1507 return; 1508 return;
1508 } 1509 }
1509 done: 1510 done:
1510 DPRINTFN(12, ("uhci_check_intr: ii=%p done\n", ii)); 1511 DPRINTFN(12, ("uhci_check_intr: ii=%p done\n", ii));
1511 usb_uncallout(ii->xfer->timeout_handle, uhci_timeout, ii); 1512 usb_uncallout(ii->xfer->timeout_handle, uhci_timeout, ii);
1512 uhci_idone(ii); 1513 uhci_idone(ii);
1513} 1514}
1514 1515
1515/* Called at splusb() */ 1516/* Called at splusb() */
1516void 1517void
1517uhci_idone(uhci_intr_info_t *ii) 1518uhci_idone(uhci_intr_info_t *ii)
1518{ 1519{
1519 usbd_xfer_handle xfer = ii->xfer; 1520 usbd_xfer_handle xfer = ii->xfer;
1520 struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe; 1521 struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
1521 uhci_soft_td_t *std; 1522 uhci_soft_td_t *std;
1522 u_int32_t status = 0, nstatus; 1523 u_int32_t status = 0, nstatus;
1523 int actlen; 1524 int actlen;
1524 1525
1525 DPRINTFN(12, ("uhci_idone: ii=%p\n", ii)); 1526 DPRINTFN(12, ("uhci_idone: ii=%p\n", ii));
1526#ifdef DIAGNOSTIC 1527#ifdef DIAGNOSTIC
1527 { 1528 {
1528 int s = splhigh(); 1529 int s = splhigh();
1529 if (ii->isdone) { 1530 if (ii->isdone) {
1530 splx(s); 1531 splx(s);
1531#ifdef UHCI_DEBUG 1532#ifdef UHCI_DEBUG
1532 printf("uhci_idone: ii is done!\n "); 1533 printf("uhci_idone: ii is done!\n ");
1533 uhci_dump_ii(ii); 1534 uhci_dump_ii(ii);
1534#else 1535#else
1535 printf("uhci_idone: ii=%p is done!\n", ii); 1536 printf("uhci_idone: ii=%p is done!\n", ii);
1536#endif 1537#endif
1537 return; 1538 return;
1538 } 1539 }
1539 ii->isdone = 1; 1540 ii->isdone = 1;
1540 splx(s); 1541 splx(s);
1541 } 1542 }
1542#endif 1543#endif
1543 1544
1544 if (xfer->nframes != 0) { 1545 if (xfer->nframes != 0) {
1545 /* Isoc transfer, do things differently. */ 1546 /* Isoc transfer, do things differently. */
1546 uhci_soft_td_t **stds = upipe->u.iso.stds; 1547 uhci_soft_td_t **stds = upipe->u.iso.stds;
1547 int i, n, nframes, len; 1548 int i, n, nframes, len;
1548 1549
1549 DPRINTFN(5,("uhci_idone: ii=%p isoc ready\n", ii)); 1550 DPRINTFN(5,("uhci_idone: ii=%p isoc ready\n", ii));
1550 1551
1551 nframes = xfer->nframes; 1552 nframes = xfer->nframes;
1552 actlen = 0; 1553 actlen = 0;
1553 n = UXFER(xfer)->curframe; 1554 n = UXFER(xfer)->curframe;
1554 for (i = 0; i < nframes; i++) { 1555 for (i = 0; i < nframes; i++) {
1555 std = stds[n]; 1556 std = stds[n];
1556#ifdef UHCI_DEBUG 1557#ifdef UHCI_DEBUG
1557 if (uhcidebug > 5) { 1558 if (uhcidebug > 5) {
1558 DPRINTFN(-1,("uhci_idone: isoc TD %d\n", i)); 1559 DPRINTFN(-1,("uhci_idone: isoc TD %d\n", i));
1559 uhci_dump_td(std); 1560 uhci_dump_td(std);
1560 } 1561 }
1561#endif 1562#endif
1562 if (++n >= UHCI_VFRAMELIST_COUNT) 1563 if (++n >= UHCI_VFRAMELIST_COUNT)
1563 n = 0; 1564 n = 0;
1564 usb_syncmem(&std->dma, 1565 usb_syncmem(&std->dma,
1565 std->offs + offsetof(uhci_td_t, td_status), 1566 std->offs + offsetof(uhci_td_t, td_status),
1566 sizeof(std->td.td_status), 1567 sizeof(std->td.td_status),
1567 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1568 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
1568 status = le32toh(std->td.td_status); 1569 status = le32toh(std->td.td_status);
1569 len = UHCI_TD_GET_ACTLEN(status); 1570 len = UHCI_TD_GET_ACTLEN(status);
1570 xfer->frlengths[i] = len; 1571 xfer->frlengths[i] = len;
1571 actlen += len; 1572 actlen += len;
1572 } 1573 }
1573 upipe->u.iso.inuse -= nframes; 1574 upipe->u.iso.inuse -= nframes;
1574 xfer->actlen = actlen; 1575 xfer->actlen = actlen;
1575 xfer->status = USBD_NORMAL_COMPLETION; 1576 xfer->status = USBD_NORMAL_COMPLETION;
1576 goto end; 1577 goto end;
1577 } 1578 }
1578 1579
1579#ifdef UHCI_DEBUG 1580#ifdef UHCI_DEBUG
1580 DPRINTFN(10, ("uhci_idone: ii=%p, xfer=%p, pipe=%p ready\n", 1581 DPRINTFN(10, ("uhci_idone: ii=%p, xfer=%p, pipe=%p ready\n",
1581 ii, xfer, upipe)); 1582 ii, xfer, upipe));
1582 if (uhcidebug > 10) 1583 if (uhcidebug > 10)
1583 uhci_dump_tds(ii->stdstart); 1584 uhci_dump_tds(ii->stdstart);
1584#endif 1585#endif
1585 1586
1586 /* The transfer is done, compute actual length and status. */ 1587 /* The transfer is done, compute actual length and status. */
1587 actlen = 0; 1588 actlen = 0;
1588 for (std = ii->stdstart; std != NULL; std = std->link.std) { 1589 for (std = ii->stdstart; std != NULL; std = std->link.std) {
1589 usb_syncmem(&std->dma, std->offs, sizeof(std->td), 1590 usb_syncmem(&std->dma, std->offs, sizeof(std->td),
1590 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1591 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
1591 nstatus = le32toh(std->td.td_status); 1592 nstatus = le32toh(std->td.td_status);
1592 if (nstatus & UHCI_TD_ACTIVE) 1593 if (nstatus & UHCI_TD_ACTIVE)
1593 break; 1594 break;
1594 1595
1595 status = nstatus; 1596 status = nstatus;
1596 if (UHCI_TD_GET_PID(le32toh(std->td.td_token)) != 1597 if (UHCI_TD_GET_PID(le32toh(std->td.td_token)) !=
1597 UHCI_TD_PID_SETUP) 1598 UHCI_TD_PID_SETUP)
1598 actlen += UHCI_TD_GET_ACTLEN(status); 1599 actlen += UHCI_TD_GET_ACTLEN(status);
1599 else { 1600 else {
1600 /* 1601 /*
1601 * UHCI will report CRCTO in addition to a STALL or NAK 1602 * UHCI will report CRCTO in addition to a STALL or NAK
1602 * for a SETUP transaction. See section 3.2.2, "TD 1603 * for a SETUP transaction. See section 3.2.2, "TD
1603 * CONTROL AND STATUS". 1604 * CONTROL AND STATUS".
1604 */ 1605 */
1605 if (status & (UHCI_TD_STALLED | UHCI_TD_NAK)) 1606 if (status & (UHCI_TD_STALLED | UHCI_TD_NAK))
1606 status &= ~UHCI_TD_CRCTO; 1607 status &= ~UHCI_TD_CRCTO;
1607 } 1608 }
1608 } 1609 }
1609 /* If there are left over TDs we need to update the toggle. */ 1610 /* If there are left over TDs we need to update the toggle. */
1610 if (std != NULL) 1611 if (std != NULL)
1611 upipe->nexttoggle = UHCI_TD_GET_DT(le32toh(std->td.td_token)); 1612 upipe->nexttoggle = UHCI_TD_GET_DT(le32toh(std->td.td_token));
1612 1613
1613 status &= UHCI_TD_ERROR; 1614 status &= UHCI_TD_ERROR;
1614 DPRINTFN(10, ("uhci_idone: actlen=%d, status=0x%x\n", 1615 DPRINTFN(10, ("uhci_idone: actlen=%d, status=0x%x\n",
1615 actlen, status)); 1616 actlen, status));
1616 xfer->actlen = actlen; 1617 xfer->actlen = actlen;
1617 if (status != 0) { 1618 if (status != 0) {
1618#ifdef UHCI_DEBUG 1619#ifdef UHCI_DEBUG
1619 char sbuf[128]; 1620 char sbuf[128];
1620 1621
1621 snprintb(sbuf, sizeof(sbuf), 1622 snprintb(sbuf, sizeof(sbuf),
1622 "\20\22BITSTUFF\23CRCTO\24NAK\25" 1623 "\20\22BITSTUFF\23CRCTO\24NAK\25"
1623 "BABBLE\26DBUFFER\27STALLED\30ACTIVE",(u_int32_t)status); 1624 "BABBLE\26DBUFFER\27STALLED\30ACTIVE",(u_int32_t)status);
1624 1625
1625 DPRINTFN((status == UHCI_TD_STALLED)*10, 1626 DPRINTFN((status == UHCI_TD_STALLED)*10,
1626 ("uhci_idone: error, addr=%d, endpt=0x%02x, " 1627 ("uhci_idone: error, addr=%d, endpt=0x%02x, "
1627 "status 0x%s\n", 1628 "status 0x%s\n",
1628 xfer->pipe->device->address, 1629 xfer->pipe->device->address,
1629 xfer->pipe->endpoint->edesc->bEndpointAddress, 1630 xfer->pipe->endpoint->edesc->bEndpointAddress,
1630 sbuf)); 1631 sbuf));
1631#endif 1632#endif
1632 1633
1633 if (status == UHCI_TD_STALLED) 1634 if (status == UHCI_TD_STALLED)
1634 xfer->status = USBD_STALLED; 1635 xfer->status = USBD_STALLED;
1635 else 1636 else
1636 xfer->status = USBD_IOERROR; /* more info XXX */ 1637 xfer->status = USBD_IOERROR; /* more info XXX */
1637 } else { 1638 } else {
1638 xfer->status = USBD_NORMAL_COMPLETION; 1639 xfer->status = USBD_NORMAL_COMPLETION;
1639 } 1640 }
1640 1641
1641 end: 1642 end:
1642 usb_transfer_complete(xfer); 1643 usb_transfer_complete(xfer);
1643 DPRINTFN(12, ("uhci_idone: ii=%p done\n", ii)); 1644 DPRINTFN(12, ("uhci_idone: ii=%p done\n", ii));
1644} 1645}
1645 1646
1646/* 1647/*
1647 * Called when a request does not complete. 1648 * Called when a request does not complete.
1648 */ 1649 */
1649void 1650void
1650uhci_timeout(void *addr) 1651uhci_timeout(void *addr)
1651{ 1652{
1652 uhci_intr_info_t *ii = addr; 1653 uhci_intr_info_t *ii = addr;
1653 struct uhci_xfer *uxfer = UXFER(ii->xfer); 1654 struct uhci_xfer *uxfer = UXFER(ii->xfer);
1654 struct uhci_pipe *upipe = (struct uhci_pipe *)uxfer->xfer.pipe; 1655 struct uhci_pipe *upipe = (struct uhci_pipe *)uxfer->xfer.pipe;
1655 uhci_softc_t *sc = upipe->pipe.device->bus->hci_private; 1656 uhci_softc_t *sc = upipe->pipe.device->bus->hci_private;
1656 1657
1657 DPRINTF(("uhci_timeout: uxfer=%p\n", uxfer)); 1658 DPRINTF(("uhci_timeout: uxfer=%p\n", uxfer));
1658 1659
1659 if (sc->sc_dying) { 1660 if (sc->sc_dying) {
1660 uhci_abort_xfer(&uxfer->xfer, USBD_TIMEOUT); 1661 uhci_abort_xfer(&uxfer->xfer, USBD_TIMEOUT);
1661 return; 1662 return;
1662 } 1663 }
1663 1664
1664 /* Execute the abort in a process context. */ 1665 /* Execute the abort in a process context. */
1665 usb_init_task(&uxfer->abort_task, uhci_timeout_task, ii->xfer); 1666 usb_init_task(&uxfer->abort_task, uhci_timeout_task, ii->xfer);
1666 usb_add_task(uxfer->xfer.pipe->device, &uxfer->abort_task, 1667 usb_add_task(uxfer->xfer.pipe->device, &uxfer->abort_task,
1667 USB_TASKQ_HC); 1668 USB_TASKQ_HC);
1668} 1669}
1669 1670
1670void 1671void
1671uhci_timeout_task(void *addr) 1672uhci_timeout_task(void *addr)
1672{ 1673{
1673 usbd_xfer_handle xfer = addr; 1674 usbd_xfer_handle xfer = addr;
1674 int s; 1675 int s;
1675 1676
1676 DPRINTF(("uhci_timeout_task: xfer=%p\n", xfer)); 1677 DPRINTF(("uhci_timeout_task: xfer=%p\n", xfer));
1677 1678
1678 s = splusb(); 1679 s = splusb();
1679 uhci_abort_xfer(xfer, USBD_TIMEOUT); 1680 uhci_abort_xfer(xfer, USBD_TIMEOUT);
1680 splx(s); 1681 splx(s);
1681} 1682}
1682 1683
1683/* 1684/*
1684 * Wait here until controller claims to have an interrupt. 1685 * Wait here until controller claims to have an interrupt.
1685 * Then call uhci_intr and return. Use timeout to avoid waiting 1686 * Then call uhci_intr and return. Use timeout to avoid waiting
1686 * too long. 1687 * too long.
1687 * Only used during boot when interrupts are not enabled yet. 1688 * Only used during boot when interrupts are not enabled yet.
1688 */ 1689 */
1689void 1690void
1690uhci_waitintr(uhci_softc_t *sc, usbd_xfer_handle xfer) 1691uhci_waitintr(uhci_softc_t *sc, usbd_xfer_handle xfer)
1691{ 1692{
1692 int timo = xfer->timeout; 1693 int timo = xfer->timeout;
1693 uhci_intr_info_t *ii; 1694 uhci_intr_info_t *ii;
1694 1695
1695 DPRINTFN(10,("uhci_waitintr: timeout = %dms\n", timo)); 1696 DPRINTFN(10,("uhci_waitintr: timeout = %dms\n", timo));
1696 1697
1697 xfer->status = USBD_IN_PROGRESS; 1698 xfer->status = USBD_IN_PROGRESS;
1698 for (; timo >= 0; timo--) { 1699 for (; timo >= 0; timo--) {
1699 usb_delay_ms(&sc->sc_bus, 1); 1700 usb_delay_ms(&sc->sc_bus, 1);
1700 DPRINTFN(20,("uhci_waitintr: 0x%04x\n", UREAD2(sc, UHCI_STS))); 1701 DPRINTFN(20,("uhci_waitintr: 0x%04x\n", UREAD2(sc, UHCI_STS)));
1701 if (UREAD2(sc, UHCI_STS) & UHCI_STS_USBINT) { 1702 if (UREAD2(sc, UHCI_STS) & UHCI_STS_USBINT) {
1702 uhci_intr1(sc); 1703 uhci_intr1(sc);
1703 if (xfer->status != USBD_IN_PROGRESS) 1704 if (xfer->status != USBD_IN_PROGRESS)
1704 return; 1705 return;
1705 } 1706 }
1706 } 1707 }
1707 1708
1708 /* Timeout */ 1709 /* Timeout */
1709 DPRINTF(("uhci_waitintr: timeout\n")); 1710 DPRINTF(("uhci_waitintr: timeout\n"));
1710 for (ii = LIST_FIRST(&sc->sc_intrhead); 1711 for (ii = LIST_FIRST(&sc->sc_intrhead);
1711 ii != NULL && ii->xfer != xfer; 1712 ii != NULL && ii->xfer != xfer;
1712 ii = LIST_NEXT(ii, list)) 1713 ii = LIST_NEXT(ii, list))
1713 ; 1714 ;
1714#ifdef DIAGNOSTIC 1715#ifdef DIAGNOSTIC
1715 if (ii == NULL) 1716 if (ii == NULL)
1716 panic("uhci_waitintr: lost intr_info"); 1717 panic("uhci_waitintr: lost intr_info");
1717#endif 1718#endif
1718 uhci_idone(ii); 1719 uhci_idone(ii);
1719} 1720}
1720 1721
1721void 1722void
1722uhci_poll(struct usbd_bus *bus) 1723uhci_poll(struct usbd_bus *bus)
1723{ 1724{
1724 uhci_softc_t *sc = bus->hci_private; 1725 uhci_softc_t *sc = bus->hci_private;
1725 1726
1726 if (UREAD2(sc, UHCI_STS) & UHCI_STS_USBINT) 1727 if (UREAD2(sc, UHCI_STS) & UHCI_STS_USBINT)
1727 uhci_intr1(sc); 1728 uhci_intr1(sc);
1728} 1729}
1729 1730
1730void 1731void
1731uhci_reset(uhci_softc_t *sc) 1732uhci_reset(uhci_softc_t *sc)
1732{ 1733{
1733 int n; 1734 int n;
1734 1735
1735 UHCICMD(sc, UHCI_CMD_HCRESET); 1736 UHCICMD(sc, UHCI_CMD_HCRESET);
1736 /* The reset bit goes low when the controller is done. */ 1737 /* The reset bit goes low when the controller is done. */
1737 for (n = 0; n < UHCI_RESET_TIMEOUT && 1738 for (n = 0; n < UHCI_RESET_TIMEOUT &&
1738 (UREAD2(sc, UHCI_CMD) & UHCI_CMD_HCRESET); n++) 1739 (UREAD2(sc, UHCI_CMD) & UHCI_CMD_HCRESET); n++)
1739 usb_delay_ms(&sc->sc_bus, 1); 1740 usb_delay_ms(&sc->sc_bus, 1);
1740 if (n >= UHCI_RESET_TIMEOUT) 1741 if (n >= UHCI_RESET_TIMEOUT)
1741 printf("%s: controller did not reset\n", 1742 printf("%s: controller did not reset\n",
1742 device_xname(sc->sc_dev)); 1743 device_xname(sc->sc_dev));
1743} 1744}
1744 1745
1745usbd_status 1746usbd_status
1746uhci_run(uhci_softc_t *sc, int run) 1747uhci_run(uhci_softc_t *sc, int run)
1747{ 1748{
1748 int s, n, running; 1749 int s, n, running;
1749 u_int16_t cmd; 1750 u_int16_t cmd;
1750 1751
1751 run = run != 0; 1752 run = run != 0;
1752 s = splhardusb(); 1753 s = splhardusb();
1753 DPRINTF(("uhci_run: setting run=%d\n", run)); 1754 DPRINTF(("uhci_run: setting run=%d\n", run));
1754 cmd = UREAD2(sc, UHCI_CMD); 1755 cmd = UREAD2(sc, UHCI_CMD);
1755 if (run) 1756 if (run)
1756 cmd |= UHCI_CMD_RS; 1757 cmd |= UHCI_CMD_RS;
1757 else 1758 else
1758 cmd &= ~UHCI_CMD_RS; 1759 cmd &= ~UHCI_CMD_RS;
1759 UHCICMD(sc, cmd); 1760 UHCICMD(sc, cmd);
1760 for(n = 0; n < 10; n++) { 1761 for(n = 0; n < 10; n++) {
1761 running = !(UREAD2(sc, UHCI_STS) & UHCI_STS_HCH); 1762 running = !(UREAD2(sc, UHCI_STS) & UHCI_STS_HCH);
1762 /* return when we've entered the state we want */ 1763 /* return when we've entered the state we want */
1763 if (run == running) { 1764 if (run == running) {
1764 splx(s); 1765 splx(s);
1765 DPRINTF(("uhci_run: done cmd=0x%x sts=0x%x\n", 1766 DPRINTF(("uhci_run: done cmd=0x%x sts=0x%x\n",
1766 UREAD2(sc, UHCI_CMD), UREAD2(sc, UHCI_STS))); 1767 UREAD2(sc, UHCI_CMD), UREAD2(sc, UHCI_STS)));
1767 return (USBD_NORMAL_COMPLETION); 1768 return (USBD_NORMAL_COMPLETION);
1768 } 1769 }
1769 usb_delay_ms(&sc->sc_bus, 1); 1770 usb_delay_ms(&sc->sc_bus, 1);
1770 } 1771 }
1771 splx(s); 1772 splx(s);
1772 printf("%s: cannot %s\n", device_xname(sc->sc_dev), 1773 printf("%s: cannot %s\n", device_xname(sc->sc_dev),
1773 run ? "start" : "stop"); 1774 run ? "start" : "stop");
1774 return (USBD_IOERROR); 1775 return (USBD_IOERROR);
1775} 1776}
1776 1777
1777/* 1778/*
1778 * Memory management routines. 1779 * Memory management routines.
1779 * uhci_alloc_std allocates TDs 1780 * uhci_alloc_std allocates TDs
1780 * uhci_alloc_sqh allocates QHs 1781 * uhci_alloc_sqh allocates QHs
1781 * These two routines do their own free list management, 1782 * These two routines do their own free list management,
1782 * partly for speed, partly because allocating DMAable memory 1783 * partly for speed, partly because allocating DMAable memory
1783 * has page size granularaity so much memory would be wasted if 1784 * has page size granularaity so much memory would be wasted if
1784 * only one TD/QH (32 bytes) was placed in each allocated chunk. 1785 * only one TD/QH (32 bytes) was placed in each allocated chunk.
1785 */ 1786 */
1786 1787
1787uhci_soft_td_t * 1788uhci_soft_td_t *
1788uhci_alloc_std(uhci_softc_t *sc) 1789uhci_alloc_std(uhci_softc_t *sc)
1789{ 1790{
1790 uhci_soft_td_t *std; 1791 uhci_soft_td_t *std;
1791 usbd_status err; 1792 usbd_status err;
1792 int i, offs; 1793 int i, offs;
1793 usb_dma_t dma; 1794 usb_dma_t dma;
1794 1795
1795 if (sc->sc_freetds == NULL) { 1796 if (sc->sc_freetds == NULL) {
1796 DPRINTFN(2,("uhci_alloc_std: allocating chunk\n")); 1797 DPRINTFN(2,("uhci_alloc_std: allocating chunk\n"));
1797 err = usb_allocmem(&sc->sc_bus, UHCI_STD_SIZE * UHCI_STD_CHUNK, 1798 err = usb_allocmem(&sc->sc_bus, UHCI_STD_SIZE * UHCI_STD_CHUNK,
1798 UHCI_TD_ALIGN, &dma); 1799 UHCI_TD_ALIGN, &dma);
1799 if (err) 1800 if (err)
1800 return (0); 1801 return (0);
1801 for(i = 0; i < UHCI_STD_CHUNK; i++) { 1802 for(i = 0; i < UHCI_STD_CHUNK; i++) {
1802 offs = i * UHCI_STD_SIZE; 1803 offs = i * UHCI_STD_SIZE;
1803 std = KERNADDR(&dma, offs); 1804 std = KERNADDR(&dma, offs);
1804 std->physaddr = DMAADDR(&dma, offs); 1805 std->physaddr = DMAADDR(&dma, offs);
1805 std->dma = dma; 1806 std->dma = dma;
1806 std->offs = offs; 1807 std->offs = offs;
1807 std->link.std = sc->sc_freetds; 1808 std->link.std = sc->sc_freetds;
1808 sc->sc_freetds = std; 1809 sc->sc_freetds = std;
1809 } 1810 }
1810 } 1811 }
1811 std = sc->sc_freetds; 1812 std = sc->sc_freetds;
1812 sc->sc_freetds = std->link.std; 1813 sc->sc_freetds = std->link.std;
1813 memset(&std->td, 0, sizeof(uhci_td_t)); 1814 memset(&std->td, 0, sizeof(uhci_td_t));
1814 return std; 1815 return std;
1815} 1816}
1816 1817
1817void 1818void
1818uhci_free_std(uhci_softc_t *sc, uhci_soft_td_t *std) 1819uhci_free_std(uhci_softc_t *sc, uhci_soft_td_t *std)
1819{ 1820{
1820#ifdef DIAGNOSTIC 1821#ifdef DIAGNOSTIC
1821#define TD_IS_FREE 0x12345678 1822#define TD_IS_FREE 0x12345678
1822 if (le32toh(std->td.td_token) == TD_IS_FREE) { 1823 if (le32toh(std->td.td_token) == TD_IS_FREE) {
1823 printf("uhci_free_std: freeing free TD %p\n", std); 1824 printf("uhci_free_std: freeing free TD %p\n", std);
1824 return; 1825 return;
1825 } 1826 }
1826 std->td.td_token = htole32(TD_IS_FREE); 1827 std->td.td_token = htole32(TD_IS_FREE);
1827#endif 1828#endif
1828 std->link.std = sc->sc_freetds; 1829 std->link.std = sc->sc_freetds;
1829 sc->sc_freetds = std; 1830 sc->sc_freetds = std;
1830} 1831}
1831 1832
1832uhci_soft_qh_t * 1833uhci_soft_qh_t *
1833uhci_alloc_sqh(uhci_softc_t *sc) 1834uhci_alloc_sqh(uhci_softc_t *sc)
1834{ 1835{
1835 uhci_soft_qh_t *sqh; 1836 uhci_soft_qh_t *sqh;
1836 usbd_status err; 1837 usbd_status err;
1837 int i, offs; 1838 int i, offs;
1838 usb_dma_t dma; 1839 usb_dma_t dma;
1839 1840
1840 if (sc->sc_freeqhs == NULL) { 1841 if (sc->sc_freeqhs == NULL) {
1841 DPRINTFN(2, ("uhci_alloc_sqh: allocating chunk\n")); 1842 DPRINTFN(2, ("uhci_alloc_sqh: allocating chunk\n"));
1842 err = usb_allocmem(&sc->sc_bus, UHCI_SQH_SIZE * UHCI_SQH_CHUNK, 1843 err = usb_allocmem(&sc->sc_bus, UHCI_SQH_SIZE * UHCI_SQH_CHUNK,
1843 UHCI_QH_ALIGN, &dma); 1844 UHCI_QH_ALIGN, &dma);
1844 if (err) 1845 if (err)
1845 return (0); 1846 return (0);
1846 for(i = 0; i < UHCI_SQH_CHUNK; i++) { 1847 for(i = 0; i < UHCI_SQH_CHUNK; i++) {
1847 offs = i * UHCI_SQH_SIZE; 1848 offs = i * UHCI_SQH_SIZE;
1848 sqh = KERNADDR(&dma, offs); 1849 sqh = KERNADDR(&dma, offs);
1849 sqh->physaddr = DMAADDR(&dma, offs); 1850 sqh->physaddr = DMAADDR(&dma, offs);
1850 sqh->dma = dma; 1851 sqh->dma = dma;
1851 sqh->offs = offs; 1852 sqh->offs = offs;
1852 sqh->hlink = sc->sc_freeqhs; 1853 sqh->hlink = sc->sc_freeqhs;
1853 sc->sc_freeqhs = sqh; 1854 sc->sc_freeqhs = sqh;
1854 } 1855 }
1855 } 1856 }
1856 sqh = sc->sc_freeqhs; 1857 sqh = sc->sc_freeqhs;
1857 sc->sc_freeqhs = sqh->hlink; 1858 sc->sc_freeqhs = sqh->hlink;
1858 memset(&sqh->qh, 0, sizeof(uhci_qh_t)); 1859 memset(&sqh->qh, 0, sizeof(uhci_qh_t));
1859 return (sqh); 1860 return (sqh);
1860} 1861}
1861 1862
1862void 1863void
1863uhci_free_sqh(uhci_softc_t *sc, uhci_soft_qh_t *sqh) 1864uhci_free_sqh(uhci_softc_t *sc, uhci_soft_qh_t *sqh)
1864{ 1865{
1865 sqh->hlink = sc->sc_freeqhs; 1866 sqh->hlink = sc->sc_freeqhs;
1866 sc->sc_freeqhs = sqh; 1867 sc->sc_freeqhs = sqh;
1867} 1868}
1868 1869
1869void 1870void
1870uhci_free_std_chain(uhci_softc_t *sc, uhci_soft_td_t *std, 1871uhci_free_std_chain(uhci_softc_t *sc, uhci_soft_td_t *std,
1871 uhci_soft_td_t *stdend) 1872 uhci_soft_td_t *stdend)
1872{ 1873{
1873 uhci_soft_td_t *p; 1874 uhci_soft_td_t *p;
1874 1875
1875 /* 1876 /*
1876 * to avoid race condition with the controller which may be looking 1877 * to avoid race condition with the controller which may be looking
1877 * at this chain, we need to first invalidate all links, and 1878 * at this chain, we need to first invalidate all links, and
1878 * then wait for the controller to move to another queue 1879 * then wait for the controller to move to another queue
1879 */ 1880 */
1880 for (p = std; p != stdend; p = p->link.std) { 1881 for (p = std; p != stdend; p = p->link.std) {
1881 usb_syncmem(&p->dma, 1882 usb_syncmem(&p->dma,
1882 p->offs + offsetof(uhci_td_t, td_link), 1883 p->offs + offsetof(uhci_td_t, td_link),
1883 sizeof(p->td.td_link), 1884 sizeof(p->td.td_link),
1884 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1885 BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
1885 if ((p->td.td_link & UHCI_PTR_T) == 0) { 1886 if ((p->td.td_link & UHCI_PTR_T) == 0) {
1886 p->td.td_link = UHCI_PTR_T; 1887 p->td.td_link = UHCI_PTR_T;
1887 usb_syncmem(&p->dma, 1888 usb_syncmem(&p->dma,
1888 p->offs + offsetof(uhci_td_t, td_link), 1889 p->offs + offsetof(uhci_td_t, td_link),
1889 sizeof(p->td.td_link), 1890 sizeof(p->td.td_link),
1890 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1891 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
1891 } 1892 }
1892 } 1893 }
1893 delay(UHCI_QH_REMOVE_DELAY); 1894 delay(UHCI_QH_REMOVE_DELAY);
1894 1895
1895 for (; std != stdend; std = p) { 1896 for (; std != stdend; std = p) {
1896 p = std->link.std; 1897 p = std->link.std;
1897 uhci_free_std(sc, std); 1898 uhci_free_std(sc, std);
1898 } 1899 }
1899} 1900}
1900 1901
1901usbd_status 1902usbd_status
1902uhci_alloc_std_chain(struct uhci_pipe *upipe, uhci_softc_t *sc, int len, 1903uhci_alloc_std_chain(struct uhci_pipe *upipe, uhci_softc_t *sc, int len,
1903 int rd, u_int16_t flags, usb_dma_t *dma, 1904 int rd, u_int16_t flags, usb_dma_t *dma,
1904 uhci_soft_td_t **sp, uhci_soft_td_t **ep) 1905 uhci_soft_td_t **sp, uhci_soft_td_t **ep)
1905{ 1906{
1906 uhci_soft_td_t *p, *lastp; 1907 uhci_soft_td_t *p, *lastp;
1907 uhci_physaddr_t lastlink; 1908 uhci_physaddr_t lastlink;
1908 int i, ntd, l, tog, maxp; 1909 int i, ntd, l, tog, maxp;
1909 u_int32_t status; 1910 u_int32_t status;
1910 int addr = upipe->pipe.device->address; 1911 int addr = upipe->pipe.device->address;
1911 int endpt = upipe->pipe.endpoint->edesc->bEndpointAddress; 1912 int endpt = upipe->pipe.endpoint->edesc->bEndpointAddress;
1912 1913
1913 DPRINTFN(8, ("uhci_alloc_std_chain: addr=%d endpt=%d len=%d speed=%d " 1914 DPRINTFN(8, ("uhci_alloc_std_chain: addr=%d endpt=%d len=%d speed=%d "
1914 "flags=0x%x\n", addr, UE_GET_ADDR(endpt), len, 1915 "flags=0x%x\n", addr, UE_GET_ADDR(endpt), len,
1915 upipe->pipe.device->speed, flags)); 1916 upipe->pipe.device->speed, flags));
1916 maxp = UGETW(upipe->pipe.endpoint->edesc->wMaxPacketSize); 1917 maxp = UGETW(upipe->pipe.endpoint->edesc->wMaxPacketSize);
1917 if (maxp == 0) { 1918 if (maxp == 0) {
1918 printf("uhci_alloc_std_chain: maxp=0\n"); 1919 printf("uhci_alloc_std_chain: maxp=0\n");
1919 return (USBD_INVAL); 1920 return (USBD_INVAL);
1920 } 1921 }
1921 ntd = (len + maxp - 1) / maxp; 1922 ntd = (len + maxp - 1) / maxp;
1922 if ((flags & USBD_FORCE_SHORT_XFER) && len % maxp == 0) 1923 if ((flags & USBD_FORCE_SHORT_XFER) && len % maxp == 0)
1923 ntd++; 1924 ntd++;
1924 DPRINTFN(10, ("uhci_alloc_std_chain: maxp=%d ntd=%d\n", maxp, ntd)); 1925 DPRINTFN(10, ("uhci_alloc_std_chain: maxp=%d ntd=%d\n", maxp, ntd));
1925 if (ntd == 0) { 1926 if (ntd == 0) {
1926 *sp = *ep = 0; 1927 *sp = *ep = 0;
1927 DPRINTFN(-1,("uhci_alloc_std_chain: ntd=0\n")); 1928 DPRINTFN(-1,("uhci_alloc_std_chain: ntd=0\n"));
1928 return (USBD_NORMAL_COMPLETION); 1929 return (USBD_NORMAL_COMPLETION);
1929 } 1930 }
1930 tog = upipe->nexttoggle; 1931 tog = upipe->nexttoggle;
1931 if (ntd % 2 == 0) 1932 if (ntd % 2 == 0)
1932 tog ^= 1; 1933 tog ^= 1;
1933 upipe->nexttoggle = tog ^ 1; 1934 upipe->nexttoggle = tog ^ 1;
1934 lastp = NULL; 1935 lastp = NULL;
1935 lastlink = UHCI_PTR_T; 1936 lastlink = UHCI_PTR_T;
1936 ntd--; 1937 ntd--;
1937 status = UHCI_TD_ZERO_ACTLEN(UHCI_TD_SET_ERRCNT(3) | UHCI_TD_ACTIVE); 1938 status = UHCI_TD_ZERO_ACTLEN(UHCI_TD_SET_ERRCNT(3) | UHCI_TD_ACTIVE);
1938 if (upipe->pipe.device->speed == USB_SPEED_LOW) 1939 if (upipe->pipe.device->speed == USB_SPEED_LOW)
1939 status |= UHCI_TD_LS; 1940 status |= UHCI_TD_LS;
1940 if (flags & USBD_SHORT_XFER_OK) 1941 if (flags & USBD_SHORT_XFER_OK)
1941 status |= UHCI_TD_SPD; 1942 status |= UHCI_TD_SPD;
1942 usb_syncmem(dma, 0, len, 1943 usb_syncmem(dma, 0, len,
1943 rd ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); 1944 rd ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
1944 for (i = ntd; i >= 0; i--) { 1945 for (i = ntd; i >= 0; i--) {
1945 p = uhci_alloc_std(sc); 1946 p = uhci_alloc_std(sc);
1946 if (p == NULL) { 1947 if (p == NULL) {
1947 KASSERT(lastp != NULL); 1948 KASSERT(lastp != NULL);
1948 uhci_free_std_chain(sc, lastp, NULL); 1949 uhci_free_std_chain(sc, lastp, NULL);
1949 return (USBD_NOMEM); 1950 return (USBD_NOMEM);
1950 } 1951 }
1951 p->link.std = lastp; 1952 p->link.std = lastp;
1952 p->td.td_link = htole32(lastlink | UHCI_PTR_VF | UHCI_PTR_TD); 1953 p->td.td_link = htole32(lastlink | UHCI_PTR_VF | UHCI_PTR_TD);
1953 lastp = p; 1954 lastp = p;
1954 lastlink = p->physaddr; 1955 lastlink = p->physaddr;
1955 p->td.td_status = htole32(status); 1956 p->td.td_status = htole32(status);
1956 if (i == ntd) { 1957 if (i == ntd) {
1957 /* last TD */ 1958 /* last TD */
1958 l = len % maxp; 1959 l = len % maxp;
1959 if (l == 0 && !(flags & USBD_FORCE_SHORT_XFER)) 1960 if (l == 0 && !(flags & USBD_FORCE_SHORT_XFER))
1960 l = maxp; 1961 l = maxp;
1961 *ep = p; 1962 *ep = p;
1962 } else 1963 } else
1963 l = maxp; 1964 l = maxp;
1964 p->td.td_token = 1965 p->td.td_token =
1965 htole32(rd ? UHCI_TD_IN (l, endpt, addr, tog) : 1966 htole32(rd ? UHCI_TD_IN (l, endpt, addr, tog) :
1966 UHCI_TD_OUT(l, endpt, addr, tog)); 1967 UHCI_TD_OUT(l, endpt, addr, tog));
1967 p->td.td_buffer = htole32(DMAADDR(dma, i * maxp)); 1968 p->td.td_buffer = htole32(DMAADDR(dma, i * maxp));
1968 usb_syncmem(&p->dma, p->offs, sizeof(p->td), 1969 usb_syncmem(&p->dma, p->offs, sizeof(p->td),
1969 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1970 BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
1970 tog ^= 1; 1971 tog ^= 1;
1971 } 1972 }
1972 *sp = lastp; 1973 *sp = lastp;
1973 DPRINTFN(10, ("uhci_alloc_std_chain: nexttog=%d\n", 1974 DPRINTFN(10, ("uhci_alloc_std_chain: nexttog=%d\n",
1974 upipe->nexttoggle)); 1975 upipe->nexttoggle));
1975 return (USBD_NORMAL_COMPLETION); 1976 return (USBD_NORMAL_COMPLETION);
1976} 1977}
1977 1978
1978void 1979void
1979uhci_device_clear_toggle(usbd_pipe_handle pipe) 1980uhci_device_clear_toggle(usbd_pipe_handle pipe)
1980{ 1981{
1981 struct uhci_pipe *upipe = (struct uhci_pipe *)pipe; 1982 struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
1982 upipe->nexttoggle = 0; 1983 upipe->nexttoggle = 0;
1983} 1984}
1984 1985
1985void 1986void
1986uhci_noop(usbd_pipe_handle pipe) 1987uhci_noop(usbd_pipe_handle pipe)
1987{ 1988{
1988} 1989}
1989 1990
1990usbd_status 1991usbd_status
1991uhci_device_bulk_transfer(usbd_xfer_handle xfer) 1992uhci_device_bulk_transfer(usbd_xfer_handle xfer)
1992{ 1993{
1993 usbd_status err; 1994 usbd_status err;
1994 1995
1995 /* Insert last in queue. */ 1996 /* Insert last in queue. */
1996 err = usb_insert_transfer(xfer); 1997 err = usb_insert_transfer(xfer);
1997 if (err) 1998 if (err)
1998 return (err); 1999 return (err);
1999 2000
2000 /* 2001 /*
2001 * Pipe isn't running (otherwise err would be USBD_INPROG), 2002 * Pipe isn't running (otherwise err would be USBD_INPROG),
2002 * so start it first. 2003 * so start it first.
2003 */ 2004 */
2004 return (uhci_device_bulk_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); 2005 return (uhci_device_bulk_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
2005} 2006}
2006 2007
2007usbd_status 2008usbd_status
2008uhci_device_bulk_start(usbd_xfer_handle xfer) 2009uhci_device_bulk_start(usbd_xfer_handle xfer)
2009{ 2010{
2010 struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe; 2011 struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
2011 usbd_device_handle dev = upipe->pipe.device; 2012 usbd_device_handle dev = upipe->pipe.device;
2012 uhci_softc_t *sc = dev->bus->hci_private; 2013 uhci_softc_t *sc = dev->bus->hci_private;
2013 uhci_intr_info_t *ii = &UXFER(xfer)->iinfo; 2014 uhci_intr_info_t *ii = &UXFER(xfer)->iinfo;
2014 uhci_soft_td_t *data, *dataend; 2015 uhci_soft_td_t *data, *dataend;
2015 uhci_soft_qh_t *sqh; 2016 uhci_soft_qh_t *sqh;
2016 usbd_status err; 2017 usbd_status err;
2017 int len, isread, endpt; 2018 int len, isread, endpt;
2018 int s; 2019 int s;
2019 2020
2020 DPRINTFN(3, ("uhci_device_bulk_start: xfer=%p len=%d flags=%d ii=%p\n", 2021 DPRINTFN(3, ("uhci_device_bulk_start: xfer=%p len=%d flags=%d ii=%p\n",
2021 xfer, xfer->length, xfer->flags, ii)); 2022 xfer, xfer->length, xfer->flags, ii));
2022 2023
2023 if (sc->sc_dying) 2024 if (sc->sc_dying)
2024 return (USBD_IOERROR); 2025 return (USBD_IOERROR);
2025 2026
2026#ifdef DIAGNOSTIC 2027#ifdef DIAGNOSTIC
2027 if (xfer->rqflags & URQ_REQUEST) 2028 if (xfer->rqflags & URQ_REQUEST)
2028 panic("uhci_device_bulk_transfer: a request"); 2029 panic("uhci_device_bulk_transfer: a request");
2029#endif 2030#endif
2030 2031
2031 len = xfer->length; 2032 len = xfer->length;
2032 endpt = upipe->pipe.endpoint->edesc->bEndpointAddress; 2033 endpt = upipe->pipe.endpoint->edesc->bEndpointAddress;
2033 isread = UE_GET_DIR(endpt) == UE_DIR_IN; 2034 isread = UE_GET_DIR(endpt) == UE_DIR_IN;
2034 sqh = upipe->u.bulk.sqh; 2035 sqh = upipe->u.bulk.sqh;
2035 2036
2036 upipe->u.bulk.isread = isread; 2037 upipe->u.bulk.isread = isread;
2037 upipe->u.bulk.length = len; 2038 upipe->u.bulk.length = len;
2038 2039
2039 err = uhci_alloc_std_chain(upipe, sc, len, isread, xfer->flags, 2040 err = uhci_alloc_std_chain(upipe, sc, len, isread, xfer->flags,
2040 &xfer->dmabuf, &data, &dataend); 2041 &xfer->dmabuf, &data, &dataend);
2041 if (err) 2042 if (err)
2042 return (err); 2043 return (err);