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