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