Annotation of sys/dev/usb/ehci.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: ehci.c,v 1.77 2007/06/15 11:41:47 mbalmer Exp $ */
2: /* $NetBSD: ehci.c,v 1.66 2004/06/30 03:11:56 mycroft Exp $ */
3:
4: /*
5: * Copyright (c) 2004 The NetBSD Foundation, Inc.
6: * All rights reserved.
7: *
8: * This code is derived from software contributed to The NetBSD Foundation
9: * by Lennart Augustsson (lennart@augustsson.net) and by Charles M. Hannum.
10: *
11: * Redistribution and use in source and binary forms, with or without
12: * modification, are permitted provided that the following conditions
13: * are met:
14: * 1. Redistributions of source code must retain the above copyright
15: * notice, this list of conditions and the following disclaimer.
16: * 2. Redistributions in binary form must reproduce the above copyright
17: * notice, this list of conditions and the following disclaimer in the
18: * documentation and/or other materials provided with the distribution.
19: * 3. All advertising materials mentioning features or use of this software
20: * must display the following acknowledgement:
21: * This product includes software developed by the NetBSD
22: * Foundation, Inc. and its contributors.
23: * 4. Neither the name of The NetBSD Foundation nor the names of its
24: * contributors may be used to endorse or promote products derived
25: * from this software without specific prior written permission.
26: *
27: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37: * POSSIBILITY OF SUCH DAMAGE.
38: */
39:
40: /*
41: * USB Enhanced Host Controller Driver, a.k.a. USB 2.0 controller.
42: *
43: * The EHCI 1.0 spec can be found at
44: * http://developer.intel.com/technology/usb/download/ehci-r10.pdf
45: * and the USB 2.0 spec at
46: * http://www.usb.org/developers/docs/usb_20.zip
47: */
48:
49: /*
50: * TODO:
51: * 1) The meaty part to implement is isochronous transactions. They are
52: * needed for USB 1 devices below USB 2.0 hubs. They are quite complicated
53: * since they need to be able to do "transaction translation", ie,
54: * converting to/from USB 2 and USB 1.
55: * So the hub driver needs to handle and schedule these things, to
56: * assign place in frame where different devices get to go. See chapter
57: * on hubs in USB 2.0 for details.
58: *
59: * 2) Command failures are not recovered correctly.
60: */
61:
62: #include <sys/param.h>
63: #include <sys/systm.h>
64: #include <sys/kernel.h>
65: #include <sys/rwlock.h>
66: #include <sys/malloc.h>
67: #include <sys/device.h>
68: #include <sys/selinfo.h>
69: #include <sys/proc.h>
70: #include <sys/queue.h>
71: #include <sys/timeout.h>
72:
73: #include <machine/bus.h>
74: #include <machine/endian.h>
75:
76: #include <dev/usb/usb.h>
77: #include <dev/usb/usbdi.h>
78: #include <dev/usb/usbdivar.h>
79: #include <dev/usb/usb_mem.h>
80: #include <dev/usb/usb_quirks.h>
81:
82: #include <dev/usb/ehcireg.h>
83: #include <dev/usb/ehcivar.h>
84:
85: #include <dev/rndvar.h>
86:
87: struct cfdriver ehci_cd = {
88: NULL, "ehci", DV_DULL
89: };
90:
91: #ifdef USB_DEBUG
92: #define EHCI_DEBUG
93: #endif
94:
95: #ifdef EHCI_DEBUG
96: #define DPRINTF(x) do { if (ehcidebug) printf x; } while(0)
97: #define DPRINTFN(n,x) do { if (ehcidebug>(n)) printf x; } while (0)
98: int ehcidebug = 0;
99: #define bitmask_snprintf(q,f,b,l) snprintf((b), (l), "%b", (q), (f))
100: #else
101: #define DPRINTF(x)
102: #define DPRINTFN(n,x)
103: #endif
104:
105: #define mstohz(ms) ((ms) * hz / 1000)
106:
107: struct ehci_pipe {
108: struct usbd_pipe pipe;
109:
110: ehci_soft_qh_t *sqh;
111: union {
112: ehci_soft_qtd_t *qtd;
113: /* ehci_soft_itd_t *itd; */
114: } tail;
115: union {
116: /* Control pipe */
117: struct {
118: usb_dma_t reqdma;
119: u_int length;
120: /*ehci_soft_qtd_t *setup, *data, *stat;*/
121: } ctl;
122: /* Interrupt pipe */
123: struct {
124: u_int length;
125: } intr;
126: /* Bulk pipe */
127: struct {
128: u_int length;
129: } bulk;
130: /* Iso pipe */
131: /* XXX */
132: } u;
133: };
134:
135: u_int8_t ehci_reverse_bits(u_int8_t, int);
136:
137: void ehci_power(int, void *);
138:
139: usbd_status ehci_open(usbd_pipe_handle);
140: void ehci_poll(struct usbd_bus *);
141: void ehci_softintr(void *);
142: int ehci_intr1(ehci_softc_t *);
143: void ehci_waitintr(ehci_softc_t *, usbd_xfer_handle);
144: void ehci_check_intr(ehci_softc_t *, struct ehci_xfer *);
145: void ehci_idone(struct ehci_xfer *);
146: void ehci_timeout(void *);
147: void ehci_timeout_task(void *);
148: void ehci_intrlist_timeout(void *);
149:
150: usbd_status ehci_allocm(struct usbd_bus *, usb_dma_t *, u_int32_t);
151: void ehci_freem(struct usbd_bus *, usb_dma_t *);
152:
153: usbd_xfer_handle ehci_allocx(struct usbd_bus *);
154: void ehci_freex(struct usbd_bus *, usbd_xfer_handle);
155:
156: usbd_status ehci_root_ctrl_transfer(usbd_xfer_handle);
157: usbd_status ehci_root_ctrl_start(usbd_xfer_handle);
158: void ehci_root_ctrl_abort(usbd_xfer_handle);
159: void ehci_root_ctrl_close(usbd_pipe_handle);
160: void ehci_root_ctrl_done(usbd_xfer_handle);
161:
162: usbd_status ehci_root_intr_transfer(usbd_xfer_handle);
163: usbd_status ehci_root_intr_start(usbd_xfer_handle);
164: void ehci_root_intr_abort(usbd_xfer_handle);
165: void ehci_root_intr_close(usbd_pipe_handle);
166: void ehci_root_intr_done(usbd_xfer_handle);
167:
168: usbd_status ehci_device_ctrl_transfer(usbd_xfer_handle);
169: usbd_status ehci_device_ctrl_start(usbd_xfer_handle);
170: void ehci_device_ctrl_abort(usbd_xfer_handle);
171: void ehci_device_ctrl_close(usbd_pipe_handle);
172: void ehci_device_ctrl_done(usbd_xfer_handle);
173:
174: usbd_status ehci_device_bulk_transfer(usbd_xfer_handle);
175: usbd_status ehci_device_bulk_start(usbd_xfer_handle);
176: void ehci_device_bulk_abort(usbd_xfer_handle);
177: void ehci_device_bulk_close(usbd_pipe_handle);
178: void ehci_device_bulk_done(usbd_xfer_handle);
179:
180: usbd_status ehci_device_intr_transfer(usbd_xfer_handle);
181: usbd_status ehci_device_intr_start(usbd_xfer_handle);
182: void ehci_device_intr_abort(usbd_xfer_handle);
183: void ehci_device_intr_close(usbd_pipe_handle);
184: void ehci_device_intr_done(usbd_xfer_handle);
185:
186: usbd_status ehci_device_isoc_transfer(usbd_xfer_handle);
187: usbd_status ehci_device_isoc_start(usbd_xfer_handle);
188: void ehci_device_isoc_abort(usbd_xfer_handle);
189: void ehci_device_isoc_close(usbd_pipe_handle);
190: void ehci_device_isoc_done(usbd_xfer_handle);
191:
192: void ehci_device_clear_toggle(usbd_pipe_handle pipe);
193: void ehci_noop(usbd_pipe_handle pipe);
194:
195: int ehci_str(usb_string_descriptor_t *, int, const char *);
196: void ehci_pcd(ehci_softc_t *, usbd_xfer_handle);
197: void ehci_pcd_able(ehci_softc_t *, int);
198: void ehci_pcd_enable(void *);
199: void ehci_disown(ehci_softc_t *, int, int);
200:
201: ehci_soft_qh_t *ehci_alloc_sqh(ehci_softc_t *);
202: void ehci_free_sqh(ehci_softc_t *, ehci_soft_qh_t *);
203:
204: ehci_soft_qtd_t *ehci_alloc_sqtd(ehci_softc_t *);
205: void ehci_free_sqtd(ehci_softc_t *, ehci_soft_qtd_t *);
206: usbd_status ehci_alloc_sqtd_chain(struct ehci_pipe *,
207: ehci_softc_t *, int, int, usbd_xfer_handle,
208: ehci_soft_qtd_t **, ehci_soft_qtd_t **);
209: void ehci_free_sqtd_chain(ehci_softc_t *, ehci_soft_qtd_t *,
210: ehci_soft_qtd_t *);
211:
212: usbd_status ehci_device_request(usbd_xfer_handle xfer);
213:
214: usbd_status ehci_device_setintr(ehci_softc_t *, ehci_soft_qh_t *,
215: int ival);
216:
217: void ehci_add_qh(ehci_soft_qh_t *, ehci_soft_qh_t *);
218: void ehci_rem_qh(ehci_softc_t *, ehci_soft_qh_t *,
219: ehci_soft_qh_t *);
220: void ehci_set_qh_qtd(ehci_soft_qh_t *, ehci_soft_qtd_t *);
221: void ehci_sync_hc(ehci_softc_t *);
222:
223: void ehci_close_pipe(usbd_pipe_handle, ehci_soft_qh_t *);
224: void ehci_abort_xfer(usbd_xfer_handle, usbd_status);
225:
226: #ifdef EHCI_DEBUG
227: void ehci_dump_regs(ehci_softc_t *);
228: void ehci_dump(void);
229: ehci_softc_t *theehci;
230: void ehci_dump_link(ehci_link_t, int);
231: void ehci_dump_sqtds(ehci_soft_qtd_t *);
232: void ehci_dump_sqtd(ehci_soft_qtd_t *);
233: void ehci_dump_qtd(ehci_qtd_t *);
234: void ehci_dump_sqh(ehci_soft_qh_t *);
235: #ifdef DIAGNOSTIC
236: void ehci_dump_exfer(struct ehci_xfer *);
237: #endif
238: #endif
239:
240: #define EHCI_NULL htole32(EHCI_LINK_TERMINATE)
241:
242: #define EHCI_INTR_ENDPT 1
243:
244: #define ehci_add_intr_list(sc, ex) \
245: LIST_INSERT_HEAD(&(sc)->sc_intrhead, (ex), inext);
246: #define ehci_del_intr_list(ex) \
247: do { \
248: LIST_REMOVE((ex), inext); \
249: (ex)->inext.le_prev = NULL; \
250: } while (0)
251: #define ehci_active_intr_list(ex) ((ex)->inext.le_prev != NULL)
252:
253: struct usbd_bus_methods ehci_bus_methods = {
254: ehci_open,
255: ehci_softintr,
256: ehci_poll,
257: ehci_allocm,
258: ehci_freem,
259: ehci_allocx,
260: ehci_freex,
261: };
262:
263: struct usbd_pipe_methods ehci_root_ctrl_methods = {
264: ehci_root_ctrl_transfer,
265: ehci_root_ctrl_start,
266: ehci_root_ctrl_abort,
267: ehci_root_ctrl_close,
268: ehci_noop,
269: ehci_root_ctrl_done,
270: };
271:
272: struct usbd_pipe_methods ehci_root_intr_methods = {
273: ehci_root_intr_transfer,
274: ehci_root_intr_start,
275: ehci_root_intr_abort,
276: ehci_root_intr_close,
277: ehci_noop,
278: ehci_root_intr_done,
279: };
280:
281: struct usbd_pipe_methods ehci_device_ctrl_methods = {
282: ehci_device_ctrl_transfer,
283: ehci_device_ctrl_start,
284: ehci_device_ctrl_abort,
285: ehci_device_ctrl_close,
286: ehci_noop,
287: ehci_device_ctrl_done,
288: };
289:
290: struct usbd_pipe_methods ehci_device_intr_methods = {
291: ehci_device_intr_transfer,
292: ehci_device_intr_start,
293: ehci_device_intr_abort,
294: ehci_device_intr_close,
295: ehci_device_clear_toggle,
296: ehci_device_intr_done,
297: };
298:
299: struct usbd_pipe_methods ehci_device_bulk_methods = {
300: ehci_device_bulk_transfer,
301: ehci_device_bulk_start,
302: ehci_device_bulk_abort,
303: ehci_device_bulk_close,
304: ehci_device_clear_toggle,
305: ehci_device_bulk_done,
306: };
307:
308: struct usbd_pipe_methods ehci_device_isoc_methods = {
309: ehci_device_isoc_transfer,
310: ehci_device_isoc_start,
311: ehci_device_isoc_abort,
312: ehci_device_isoc_close,
313: ehci_noop,
314: ehci_device_isoc_done,
315: };
316:
317: /*
318: * Reverse a number with nbits bits. Used to evenly distribute lower-level
319: * interrupt heads in the periodic schedule.
320: * Suitable for use with EHCI_IPOLLRATES <= 9.
321: */
322: u_int8_t
323: ehci_reverse_bits(u_int8_t c, int nbits)
324: {
325: c = ((c >> 1) & 0x55) | ((c << 1) & 0xaa);
326: c = ((c >> 2) & 0x33) | ((c << 2) & 0xcc);
327: c = ((c >> 4) & 0x0f) | ((c << 4) & 0xf0);
328:
329: return c >> (8 - nbits);
330: }
331:
332: usbd_status
333: ehci_init(ehci_softc_t *sc)
334: {
335: u_int32_t sparams, cparams, hcr;
336: u_int i, j;
337: usbd_status err;
338: ehci_soft_qh_t *sqh;
339:
340: #ifdef EHCI_DEBUG
341: u_int32_t vers;
342: theehci = sc;
343:
344: DPRINTF(("ehci_init: start\n"));
345:
346: vers = EREAD2(sc, EHCI_HCIVERSION);
347: DPRINTF(("%s: EHCI version %x.%x\n", sc->sc_bus.bdev.dv_xname,
348: vers >> 8, vers & 0xff));
349: #endif
350:
351: sc->sc_offs = EREAD1(sc, EHCI_CAPLENGTH);
352:
353: sparams = EREAD4(sc, EHCI_HCSPARAMS);
354: DPRINTF(("ehci_init: sparams=0x%x\n", sparams));
355: sc->sc_noport = EHCI_HCS_N_PORTS(sparams);
356: cparams = EREAD4(sc, EHCI_HCCPARAMS);
357: DPRINTF(("ehci_init: cparams=0x%x\n", cparams));
358:
359: /* MUST clear segment register if 64 bit capable. */
360: if (EHCI_HCC_64BIT(cparams))
361: EWRITE4(sc, EHCI_CTRLDSSEGMENT, 0);
362:
363: sc->sc_bus.usbrev = USBREV_2_0;
364:
365: /* Reset the controller */
366: DPRINTF(("%s: resetting\n", sc->sc_bus.bdev.dv_xname));
367: EOWRITE4(sc, EHCI_USBCMD, 0); /* Halt controller */
368: usb_delay_ms(&sc->sc_bus, 1);
369: EOWRITE4(sc, EHCI_USBCMD, EHCI_CMD_HCRESET);
370: for (i = 0; i < 100; i++) {
371: usb_delay_ms(&sc->sc_bus, 1);
372: hcr = EOREAD4(sc, EHCI_USBCMD) & EHCI_CMD_HCRESET;
373: if (!hcr)
374: break;
375: }
376: if (hcr) {
377: printf("%s: reset timeout\n",
378: sc->sc_bus.bdev.dv_xname);
379: return (USBD_IOERROR);
380: }
381:
382: /* XXX need proper intr scheduling */
383: sc->sc_rand = 96;
384:
385: /* frame list size at default, read back what we got and use that */
386: switch (EHCI_CMD_FLS(EOREAD4(sc, EHCI_USBCMD))) {
387: case 0: sc->sc_flsize = 1024; break;
388: case 1: sc->sc_flsize = 512; break;
389: case 2: sc->sc_flsize = 256; break;
390: case 3: return (USBD_IOERROR);
391: }
392: err = usb_allocmem(&sc->sc_bus, sc->sc_flsize * sizeof(ehci_link_t),
393: EHCI_FLALIGN_ALIGN, &sc->sc_fldma);
394: if (err)
395: return (err);
396: DPRINTF(("%s: flsize=%d\n", sc->sc_bus.bdev.dv_xname,sc->sc_flsize));
397: sc->sc_flist = KERNADDR(&sc->sc_fldma, 0);
398: EOWRITE4(sc, EHCI_PERIODICLISTBASE, DMAADDR(&sc->sc_fldma, 0));
399:
400: /* Set up the bus struct. */
401: sc->sc_bus.methods = &ehci_bus_methods;
402: sc->sc_bus.pipe_size = sizeof(struct ehci_pipe);
403:
404: sc->sc_powerhook = powerhook_establish(ehci_power, sc);
405:
406: sc->sc_eintrs = EHCI_NORMAL_INTRS;
407:
408: /*
409: * Allocate the interrupt dummy QHs. These are arranged to give poll
410: * intervals that are powers of 2 times 1ms.
411: */
412: for (i = 0; i < EHCI_INTRQHS; i++) {
413: sqh = ehci_alloc_sqh(sc);
414: if (sqh == NULL) {
415: err = USBD_NOMEM;
416: goto bad1;
417: }
418: sc->sc_islots[i].sqh = sqh;
419: }
420: for (i = 0; i < EHCI_INTRQHS; i++) {
421: sqh = sc->sc_islots[i].sqh;
422: if (i == 0) {
423: /* The last (1ms) QH terminates. */
424: sqh->qh.qh_link = EHCI_NULL;
425: sqh->next = NULL;
426: } else {
427: /* Otherwise the next QH has half the poll interval */
428: sqh->next = sc->sc_islots[(i + 1) / 2 - 1].sqh;
429: sqh->qh.qh_link = htole32(sqh->next->physaddr |
430: EHCI_LINK_QH);
431: }
432: sqh->qh.qh_endp = htole32(EHCI_QH_SET_EPS(EHCI_QH_SPEED_HIGH));
433: sqh->qh.qh_endphub = htole32(EHCI_QH_SET_MULT(1));
434: sqh->qh.qh_curqtd = EHCI_NULL;
435: sqh->qh.qh_qtd.qtd_next = EHCI_NULL;
436: sqh->qh.qh_qtd.qtd_altnext = EHCI_NULL;
437: sqh->qh.qh_qtd.qtd_status = htole32(EHCI_QTD_HALTED);
438: sqh->sqtd = NULL;
439: }
440: /* Point the frame list at the last level (128ms). */
441: for (i = 0; i < (1 << (EHCI_IPOLLRATES - 1)); i++)
442: for (j = i; j < sc->sc_flsize; j += 1 << (EHCI_IPOLLRATES - 1))
443: sc->sc_flist[j] = htole32(EHCI_LINK_QH | sc->sc_islots[
444: EHCI_IQHIDX(EHCI_IPOLLRATES - 1, ehci_reverse_bits(
445: i, EHCI_IPOLLRATES - 1))].sqh->physaddr);
446:
447: /* Allocate dummy QH that starts the async list. */
448: sqh = ehci_alloc_sqh(sc);
449: if (sqh == NULL) {
450: err = USBD_NOMEM;
451: goto bad1;
452: }
453: /* Fill the QH */
454: sqh->qh.qh_endp =
455: htole32(EHCI_QH_SET_EPS(EHCI_QH_SPEED_HIGH) | EHCI_QH_HRECL);
456: sqh->qh.qh_link =
457: htole32(sqh->physaddr | EHCI_LINK_QH);
458: sqh->qh.qh_curqtd = EHCI_NULL;
459: sqh->prev = sqh; /*It's a circular list.. */
460: sqh->next = sqh;
461: /* Fill the overlay qTD */
462: sqh->qh.qh_qtd.qtd_next = EHCI_NULL;
463: sqh->qh.qh_qtd.qtd_altnext = EHCI_NULL;
464: sqh->qh.qh_qtd.qtd_status = htole32(EHCI_QTD_HALTED);
465: sqh->sqtd = NULL;
466: #ifdef EHCI_DEBUG
467: if (ehcidebug)
468: ehci_dump_sqh(sqh);
469: #endif
470:
471: /* Point to async list */
472: sc->sc_async_head = sqh;
473: EOWRITE4(sc, EHCI_ASYNCLISTADDR, sqh->physaddr | EHCI_LINK_QH);
474:
475: timeout_set(&sc->sc_tmo_pcd, NULL, NULL);
476: timeout_set(&sc->sc_tmo_intrlist, NULL, NULL);
477:
478: rw_init(&sc->sc_doorbell_lock, "ehcidb");
479:
480: /* Turn on controller */
481: EOWRITE4(sc, EHCI_USBCMD,
482: EHCI_CMD_ITC_2 | /* 2 microframes interrupt delay */
483: (EOREAD4(sc, EHCI_USBCMD) & EHCI_CMD_FLS_M) |
484: EHCI_CMD_ASE |
485: EHCI_CMD_PSE |
486: EHCI_CMD_RS);
487:
488: /* Take over port ownership */
489: EOWRITE4(sc, EHCI_CONFIGFLAG, EHCI_CONF_CF);
490:
491: for (i = 0; i < 100; i++) {
492: usb_delay_ms(&sc->sc_bus, 1);
493: hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH;
494: if (!hcr)
495: break;
496: }
497: if (hcr) {
498: printf("%s: run timeout\n", sc->sc_bus.bdev.dv_xname);
499: return (USBD_IOERROR);
500: }
501:
502: /* Enable interrupts */
503: DPRINTFN(1,("ehci_init: enabling\n"));
504: EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs);
505:
506: return (USBD_NORMAL_COMPLETION);
507:
508: #if 0
509: bad2:
510: ehci_free_sqh(sc, sc->sc_async_head);
511: #endif
512: bad1:
513: usb_freemem(&sc->sc_bus, &sc->sc_fldma);
514: return (err);
515: }
516:
517: int
518: ehci_intr(void *v)
519: {
520: ehci_softc_t *sc = v;
521:
522: if (sc == NULL || sc->sc_dying)
523: return (0);
524:
525: /* If we get an interrupt while polling, then just ignore it. */
526: if (sc->sc_bus.use_polling) {
527: u_int32_t intrs = EHCI_STS_INTRS(EOREAD4(sc, EHCI_USBSTS));
528:
529: if (intrs)
530: EOWRITE4(sc, EHCI_USBSTS, intrs); /* Acknowledge */
531: return (0);
532: }
533:
534: return (ehci_intr1(sc));
535: }
536:
537: int
538: ehci_intr1(ehci_softc_t *sc)
539: {
540: u_int32_t intrs, eintrs;
541:
542: DPRINTFN(20,("ehci_intr1: enter\n"));
543:
544: /* In case the interrupt occurs before initialization has completed. */
545: if (sc == NULL) {
546: #ifdef DIAGNOSTIC
547: printf("ehci_intr1: sc == NULL\n");
548: #endif
549: return (0);
550: }
551:
552: intrs = EHCI_STS_INTRS(EOREAD4(sc, EHCI_USBSTS));
553: if (!intrs)
554: return (0);
555:
556: eintrs = intrs & sc->sc_eintrs;
557: DPRINTFN(7, ("ehci_intr1: sc=%p intrs=0x%x(0x%x) eintrs=0x%x\n",
558: sc, (u_int)intrs, EOREAD4(sc, EHCI_USBSTS), (u_int)eintrs));
559: if (!eintrs)
560: return (0);
561:
562: EOWRITE4(sc, EHCI_USBSTS, intrs); /* Acknowledge */
563: sc->sc_bus.intr_context++;
564: sc->sc_bus.no_intrs++;
565: if (eintrs & EHCI_STS_IAA) {
566: DPRINTF(("ehci_intr1: door bell\n"));
567: wakeup(&sc->sc_async_head);
568: eintrs &= ~EHCI_STS_IAA;
569: }
570: if (eintrs & (EHCI_STS_INT | EHCI_STS_ERRINT)) {
571: DPRINTFN(5,("ehci_intr1: %s %s\n",
572: eintrs & EHCI_STS_INT ? "INT" : "",
573: eintrs & EHCI_STS_ERRINT ? "ERRINT" : ""));
574: usb_schedsoftintr(&sc->sc_bus);
575: eintrs &= ~(EHCI_STS_INT | EHCI_STS_ERRINT);
576: }
577: if (eintrs & EHCI_STS_HSE) {
578: printf("%s: unrecoverable error, controller halted\n",
579: sc->sc_bus.bdev.dv_xname);
580: /* XXX what else */
581: }
582: if (eintrs & EHCI_STS_PCD) {
583: ehci_pcd(sc, sc->sc_intrxfer);
584: /*
585: * Disable PCD interrupt for now, because it will be
586: * on until the port has been reset.
587: */
588: ehci_pcd_able(sc, 0);
589: /* Do not allow RHSC interrupts > 1 per second */
590: timeout_del(&sc->sc_tmo_pcd);
591: timeout_set(&sc->sc_tmo_pcd, ehci_pcd_enable, sc);
592: timeout_add(&sc->sc_tmo_pcd, hz);
593: eintrs &= ~EHCI_STS_PCD;
594: }
595:
596: sc->sc_bus.intr_context--;
597:
598: if (eintrs != 0) {
599: /* Block unprocessed interrupts. */
600: sc->sc_eintrs &= ~eintrs;
601: EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs);
602: printf("%s: blocking intrs 0x%x\n",
603: sc->sc_bus.bdev.dv_xname, eintrs);
604: }
605:
606: return (1);
607: }
608:
609: void
610: ehci_pcd_able(ehci_softc_t *sc, int on)
611: {
612: DPRINTFN(4, ("ehci_pcd_able: on=%d\n", on));
613: if (on)
614: sc->sc_eintrs |= EHCI_STS_PCD;
615: else
616: sc->sc_eintrs &= ~EHCI_STS_PCD;
617: EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs);
618: }
619:
620: void
621: ehci_pcd_enable(void *v_sc)
622: {
623: ehci_softc_t *sc = v_sc;
624:
625: ehci_pcd_able(sc, 1);
626: }
627:
628: void
629: ehci_pcd(ehci_softc_t *sc, usbd_xfer_handle xfer)
630: {
631: usbd_pipe_handle pipe;
632: u_char *p;
633: int i, m;
634:
635: if (xfer == NULL) {
636: /* Just ignore the change. */
637: return;
638: }
639:
640: pipe = xfer->pipe;
641:
642: p = KERNADDR(&xfer->dmabuf, 0);
643: m = min(sc->sc_noport, xfer->length * 8 - 1);
644: memset(p, 0, xfer->length);
645: for (i = 1; i <= m; i++) {
646: /* Pick out CHANGE bits from the status reg. */
647: if (EOREAD4(sc, EHCI_PORTSC(i)) & EHCI_PS_CLEAR)
648: p[i/8] |= 1 << (i%8);
649: }
650: DPRINTF(("ehci_pcd: change=0x%02x\n", *p));
651: xfer->actlen = xfer->length;
652: xfer->status = USBD_NORMAL_COMPLETION;
653:
654: usb_transfer_complete(xfer);
655: }
656:
657: void
658: ehci_softintr(void *v)
659: {
660: ehci_softc_t *sc = v;
661: struct ehci_xfer *ex, *nextex;
662:
663: DPRINTFN(10,("%s: ehci_softintr (%d)\n", sc->sc_bus.bdev.dv_xname,
664: sc->sc_bus.intr_context));
665:
666: sc->sc_bus.intr_context++;
667:
668: /*
669: * The only explanation I can think of for why EHCI is as brain dead
670: * as UHCI interrupt-wise is that Intel was involved in both.
671: * An interrupt just tells us that something is done, we have no
672: * clue what, so we need to scan through all active transfers. :-(
673: */
674: for (ex = LIST_FIRST(&sc->sc_intrhead); ex; ex = nextex) {
675: nextex = LIST_NEXT(ex, inext);
676: ehci_check_intr(sc, ex);
677: }
678:
679: /* Schedule a callout to catch any dropped transactions. */
680: if ((sc->sc_flags & EHCIF_DROPPED_INTR_WORKAROUND) &&
681: !LIST_EMPTY(&sc->sc_intrhead)) {
682: timeout_del(&sc->sc_tmo_intrlist);
683: timeout_set(&sc->sc_tmo_intrlist, ehci_intrlist_timeout, sc);
684: timeout_add(&sc->sc_tmo_intrlist, hz);
685: }
686:
687: #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
688: if (sc->sc_softwake) {
689: sc->sc_softwake = 0;
690: wakeup(&sc->sc_softwake);
691: }
692: #endif /* __HAVE_GENERIC_SOFT_INTERRUPTS */
693:
694: sc->sc_bus.intr_context--;
695: }
696:
697: /* Check for an interrupt. */
698: void
699: ehci_check_intr(ehci_softc_t *sc, struct ehci_xfer *ex)
700: {
701: ehci_soft_qtd_t *sqtd, *lsqtd;
702: u_int32_t status;
703:
704: DPRINTFN(/*15*/2, ("ehci_check_intr: ex=%p\n", ex));
705:
706: if (ex->sqtdstart == NULL) {
707: printf("ehci_check_intr: sqtdstart=NULL\n");
708: return;
709: }
710: lsqtd = ex->sqtdend;
711: #ifdef DIAGNOSTIC
712: if (lsqtd == NULL) {
713: printf("ehci_check_intr: lsqtd==0\n");
714: return;
715: }
716: #endif
717: /*
718: * If the last TD is still active we need to check whether there
719: * is a an error somewhere in the middle, or whether there was a
720: * short packet (SPD and not ACTIVE).
721: */
722: if (letoh32(lsqtd->qtd.qtd_status) & EHCI_QTD_ACTIVE) {
723: DPRINTFN(12, ("ehci_check_intr: active ex=%p\n", ex));
724: for (sqtd = ex->sqtdstart; sqtd != lsqtd; sqtd=sqtd->nextqtd) {
725: status = letoh32(sqtd->qtd.qtd_status);
726: /* If there's an active QTD the xfer isn't done. */
727: if (status & EHCI_QTD_ACTIVE)
728: break;
729: /* Any kind of error makes the xfer done. */
730: if (status & EHCI_QTD_HALTED)
731: goto done;
732: /* We want short packets, and it is short: it's done */
733: if (EHCI_QTD_GET_BYTES(status) != 0)
734: goto done;
735: }
736: DPRINTFN(12, ("ehci_check_intr: ex=%p std=%p still active\n",
737: ex, ex->sqtdstart));
738: return;
739: }
740: done:
741: DPRINTFN(12, ("ehci_check_intr: ex=%p done\n", ex));
742: timeout_del(&ex->xfer.timeout_handle);
743: usb_rem_task(ex->xfer.pipe->device, &ex->abort_task);
744: ehci_idone(ex);
745: }
746:
747: void
748: ehci_idone(struct ehci_xfer *ex)
749: {
750: usbd_xfer_handle xfer = &ex->xfer;
751: #ifdef EHCI_DEBUG
752: struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
753: #endif
754: ehci_soft_qtd_t *sqtd, *lsqtd;
755: u_int32_t status = 0, nstatus = 0;
756: int actlen, cerr;
757:
758: DPRINTFN(/*12*/2, ("ehci_idone: ex=%p\n", ex));
759: #ifdef DIAGNOSTIC
760: {
761: int s = splhigh();
762: if (ex->isdone) {
763: splx(s);
764: #ifdef EHCI_DEBUG
765: printf("ehci_idone: ex is done!\n ");
766: ehci_dump_exfer(ex);
767: #else
768: printf("ehci_idone: ex=%p is done!\n", ex);
769: #endif
770: return;
771: }
772: ex->isdone = 1;
773: splx(s);
774: }
775: #endif
776:
777: if (xfer->status == USBD_CANCELLED ||
778: xfer->status == USBD_TIMEOUT) {
779: DPRINTF(("ehci_idone: aborted xfer=%p\n", xfer));
780: return;
781: }
782:
783: #ifdef EHCI_DEBUG
784: DPRINTFN(/*10*/2, ("ehci_idone: xfer=%p, pipe=%p ready\n", xfer, epipe));
785: if (ehcidebug > 10)
786: ehci_dump_sqtds(ex->sqtdstart);
787: #endif
788:
789: /* The transfer is done, compute actual length and status. */
790: lsqtd = ex->sqtdend;
791: actlen = 0;
792: for (sqtd = ex->sqtdstart; sqtd != lsqtd->nextqtd;
793: sqtd = sqtd->nextqtd) {
794: nstatus = letoh32(sqtd->qtd.qtd_status);
795: if (nstatus & EHCI_QTD_ACTIVE)
796: break;
797:
798: status = nstatus;
799: /* halt is ok if descriptor is last, and complete */
800: if (sqtd->qtd.qtd_next == EHCI_NULL &&
801: EHCI_QTD_GET_BYTES(status) == 0)
802: status &= ~EHCI_QTD_HALTED;
803: if (EHCI_QTD_GET_PID(status) != EHCI_QTD_PID_SETUP)
804: actlen += sqtd->len - EHCI_QTD_GET_BYTES(status);
805: }
806:
807: cerr = EHCI_QTD_GET_CERR(status);
808: DPRINTFN(/*10*/2, ("ehci_idone: len=%d, actlen=%d, cerr=%d, "
809: "status=0x%x\n", xfer->length, actlen, cerr, status));
810: xfer->actlen = actlen;
811: if ((status & EHCI_QTD_HALTED) != 0) {
812: #ifdef EHCI_DEBUG
813: char sbuf[128];
814:
815: bitmask_snprintf((u_int32_t)status,
816: "\20\7HALTED\6BUFERR\5BABBLE\4XACTERR"
817: "\3MISSED\2SPLIT\1PING", sbuf, sizeof(sbuf));
818:
819: DPRINTFN(2,
820: ("ehci_idone: error, addr=%d, endpt=0x%02x, "
821: "status 0x%s\n",
822: xfer->pipe->device->address,
823: xfer->pipe->endpoint->edesc->bEndpointAddress,
824: sbuf));
825: if (ehcidebug > 2) {
826: ehci_dump_sqh(epipe->sqh);
827: ehci_dump_sqtds(ex->sqtdstart);
828: }
829: #endif
830: if ((status & EHCI_QTD_BABBLE) == 0 && cerr > 0)
831: xfer->status = USBD_STALLED;
832: else
833: xfer->status = USBD_IOERROR; /* more info XXX */
834: } else
835: xfer->status = USBD_NORMAL_COMPLETION;
836:
837: usb_transfer_complete(xfer);
838: DPRINTFN(/*12*/2, ("ehci_idone: ex=%p done\n", ex));
839: }
840:
841: /*
842: * Wait here until controller claims to have an interrupt.
843: * Then call ehci_intr and return. Use timeout to avoid waiting
844: * too long.
845: */
846: void
847: ehci_waitintr(ehci_softc_t *sc, usbd_xfer_handle xfer)
848: {
849: int timo;
850: u_int32_t intrs;
851:
852: xfer->status = USBD_IN_PROGRESS;
853: for (timo = xfer->timeout; timo >= 0; timo--) {
854: usb_delay_ms(&sc->sc_bus, 1);
855: if (sc->sc_dying)
856: break;
857: intrs = EHCI_STS_INTRS(EOREAD4(sc, EHCI_USBSTS)) &
858: sc->sc_eintrs;
859: DPRINTFN(15,("ehci_waitintr: 0x%04x\n", intrs));
860: #ifdef EHCI_DEBUG
861: if (ehcidebug > 15)
862: ehci_dump_regs(sc);
863: #endif
864: if (intrs) {
865: ehci_intr1(sc);
866: if (xfer->status != USBD_IN_PROGRESS)
867: return;
868: }
869: }
870:
871: /* Timeout */
872: DPRINTF(("ehci_waitintr: timeout\n"));
873: xfer->status = USBD_TIMEOUT;
874: usb_transfer_complete(xfer);
875: /* XXX should free TD */
876: }
877:
878: void
879: ehci_poll(struct usbd_bus *bus)
880: {
881: ehci_softc_t *sc = (ehci_softc_t *)bus;
882: #ifdef EHCI_DEBUG
883: static int last;
884: int new;
885: new = EHCI_STS_INTRS(EOREAD4(sc, EHCI_USBSTS));
886: if (new != last) {
887: DPRINTFN(10,("ehci_poll: intrs=0x%04x\n", new));
888: last = new;
889: }
890: #endif
891:
892: if (EOREAD4(sc, EHCI_USBSTS) & sc->sc_eintrs)
893: ehci_intr1(sc);
894: }
895:
896: int
897: ehci_detach(struct ehci_softc *sc, int flags)
898: {
899: int rv = 0;
900:
901: if (sc->sc_child != NULL)
902: rv = config_detach(sc->sc_child, flags);
903:
904: if (rv != 0)
905: return (rv);
906:
907: timeout_del(&sc->sc_tmo_intrlist);
908: timeout_del(&sc->sc_tmo_pcd);
909:
910: if (sc->sc_powerhook != NULL)
911: powerhook_disestablish(sc->sc_powerhook);
912: if (sc->sc_shutdownhook != NULL)
913: shutdownhook_disestablish(sc->sc_shutdownhook);
914:
915: usb_delay_ms(&sc->sc_bus, 300); /* XXX let stray task complete */
916:
917: /* XXX free other data structures XXX */
918:
919: return (rv);
920: }
921:
922:
923: int
924: ehci_activate(struct device *self, enum devact act)
925: {
926: struct ehci_softc *sc = (struct ehci_softc *)self;
927: int rv = 0;
928:
929: switch (act) {
930: case DVACT_ACTIVATE:
931: break;
932:
933: case DVACT_DEACTIVATE:
934: if (sc->sc_child != NULL)
935: rv = config_deactivate(sc->sc_child);
936: sc->sc_dying = 1;
937: break;
938: }
939: return (rv);
940: }
941:
942: /*
943: * Handle suspend/resume.
944: *
945: * We need to switch to polling mode here, because this routine is
946: * called from an interrupt context. This is all right since we
947: * are almost suspended anyway.
948: */
949: void
950: ehci_power(int why, void *v)
951: {
952: ehci_softc_t *sc = v;
953: u_int32_t cmd, hcr;
954: int s, i;
955:
956: #ifdef EHCI_DEBUG
957: DPRINTF(("ehci_power: sc=%p, why=%d\n", sc, why));
958: if (ehcidebug > 0)
959: ehci_dump_regs(sc);
960: #endif
961:
962: s = splhardusb();
963: switch (why) {
964: case PWR_SUSPEND:
965: case PWR_STANDBY:
966: sc->sc_bus.use_polling++;
967:
968: for (i = 1; i <= sc->sc_noport; i++) {
969: cmd = EOREAD4(sc, EHCI_PORTSC(i));
970: if ((cmd & (EHCI_PS_PO|EHCI_PS_PE)) == EHCI_PS_PE)
971: EOWRITE4(sc, EHCI_PORTSC(i),
972: cmd | EHCI_PS_SUSP);
973: }
974:
975: sc->sc_cmd = EOREAD4(sc, EHCI_USBCMD);
976: cmd = sc->sc_cmd & ~(EHCI_CMD_ASE | EHCI_CMD_PSE);
977: EOWRITE4(sc, EHCI_USBCMD, cmd);
978:
979: for (i = 0; i < 100; i++) {
980: hcr = EOREAD4(sc, EHCI_USBSTS) &
981: (EHCI_STS_ASS | EHCI_STS_PSS);
982: if (hcr == 0)
983: break;
984:
985: usb_delay_ms(&sc->sc_bus, 1);
986: }
987: if (hcr != 0)
988: printf("%s: reset timeout\n",
989: sc->sc_bus.bdev.dv_xname);
990:
991: cmd &= ~EHCI_CMD_RS;
992: EOWRITE4(sc, EHCI_USBCMD, cmd);
993:
994: for (i = 0; i < 100; i++) {
995: hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH;
996: if (hcr == EHCI_STS_HCH)
997: break;
998:
999: usb_delay_ms(&sc->sc_bus, 1);
1000: }
1001: if (hcr != EHCI_STS_HCH)
1002: printf("%s: config timeout\n",
1003: sc->sc_bus.bdev.dv_xname);
1004:
1005: sc->sc_bus.use_polling--;
1006: break;
1007:
1008: case PWR_RESUME:
1009: sc->sc_bus.use_polling++;
1010:
1011: /* restore things in case the bios sucks */
1012: EOWRITE4(sc, EHCI_CTRLDSSEGMENT, 0);
1013: EOWRITE4(sc, EHCI_PERIODICLISTBASE, DMAADDR(&sc->sc_fldma, 0));
1014: EOWRITE4(sc, EHCI_ASYNCLISTADDR,
1015: sc->sc_async_head->physaddr | EHCI_LINK_QH);
1016: EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs);
1017:
1018: hcr = 0;
1019: for (i = 1; i <= sc->sc_noport; i++) {
1020: cmd = EOREAD4(sc, EHCI_PORTSC(i));
1021: if ((cmd & (EHCI_PS_PO|EHCI_PS_SUSP)) == EHCI_PS_SUSP) {
1022: EOWRITE4(sc, EHCI_PORTSC(i),
1023: cmd | EHCI_PS_FPR);
1024: hcr = 1;
1025: }
1026: }
1027:
1028: if (hcr) {
1029: usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT);
1030: for (i = 1; i <= sc->sc_noport; i++) {
1031: cmd = EOREAD4(sc, EHCI_PORTSC(i));
1032: if ((cmd & (EHCI_PS_PO|EHCI_PS_SUSP)) ==
1033: EHCI_PS_SUSP)
1034: EOWRITE4(sc, EHCI_PORTSC(i),
1035: cmd & ~EHCI_PS_FPR);
1036: }
1037: }
1038:
1039: EOWRITE4(sc, EHCI_USBCMD, sc->sc_cmd);
1040:
1041: /* Take over port ownership */
1042: EOWRITE4(sc, EHCI_CONFIGFLAG, EHCI_CONF_CF);
1043:
1044: for (i = 0; i < 100; i++) {
1045: hcr = EOREAD4(sc, EHCI_USBSTS) & EHCI_STS_HCH;
1046: if (hcr != EHCI_STS_HCH)
1047: break;
1048:
1049: usb_delay_ms(&sc->sc_bus, 1);
1050: }
1051: if (hcr == EHCI_STS_HCH)
1052: printf("%s: config timeout\n",
1053: sc->sc_bus.bdev.dv_xname);
1054:
1055: usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT);
1056:
1057: sc->sc_bus.use_polling--;
1058: break;
1059: }
1060: splx(s);
1061:
1062: #ifdef EHCI_DEBUG
1063: DPRINTF(("ehci_power: sc=%p\n", sc));
1064: if (ehcidebug > 0)
1065: ehci_dump_regs(sc);
1066: #endif
1067: }
1068:
1069: /*
1070: * Shut down the controller when the system is going down.
1071: */
1072: void
1073: ehci_shutdown(void *v)
1074: {
1075: ehci_softc_t *sc = v;
1076:
1077: DPRINTF(("ehci_shutdown: stopping the HC\n"));
1078: EOWRITE4(sc, EHCI_USBCMD, 0); /* Halt controller */
1079: EOWRITE4(sc, EHCI_USBCMD, EHCI_CMD_HCRESET);
1080: }
1081:
1082: usbd_status
1083: ehci_allocm(struct usbd_bus *bus, usb_dma_t *dma, u_int32_t size)
1084: {
1085: struct ehci_softc *sc = (struct ehci_softc *)bus;
1086: usbd_status err;
1087:
1088: err = usb_allocmem(&sc->sc_bus, size, 0, dma);
1089: #ifdef EHCI_DEBUG
1090: if (err)
1091: printf("ehci_allocm: usb_allocmem()=%d\n", err);
1092: #endif
1093: return (err);
1094: }
1095:
1096: void
1097: ehci_freem(struct usbd_bus *bus, usb_dma_t *dma)
1098: {
1099: struct ehci_softc *sc = (struct ehci_softc *)bus;
1100:
1101: usb_freemem(&sc->sc_bus, dma);
1102: }
1103:
1104: usbd_xfer_handle
1105: ehci_allocx(struct usbd_bus *bus)
1106: {
1107: struct ehci_softc *sc = (struct ehci_softc *)bus;
1108: usbd_xfer_handle xfer;
1109:
1110: xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers);
1111: if (xfer != NULL) {
1112: SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, next);
1113: #ifdef DIAGNOSTIC
1114: if (xfer->busy_free != XFER_FREE)
1115: printf("ehci_allocx: xfer=%p not free, 0x%08x\n",
1116: xfer, xfer->busy_free);
1117: #endif
1118: } else
1119: xfer = malloc(sizeof(struct ehci_xfer), M_USB, M_NOWAIT);
1120:
1121: if (xfer != NULL) {
1122: memset(xfer, 0, sizeof(struct ehci_xfer));
1123: usb_init_task(&EXFER(xfer)->abort_task, ehci_timeout_task,
1124: xfer);
1125: EXFER(xfer)->ehci_xfer_flags = 0;
1126: #ifdef DIAGNOSTIC
1127: EXFER(xfer)->isdone = 1;
1128: xfer->busy_free = XFER_BUSY;
1129: #endif
1130: }
1131: return (xfer);
1132: }
1133:
1134: void
1135: ehci_freex(struct usbd_bus *bus, usbd_xfer_handle xfer)
1136: {
1137: struct ehci_softc *sc = (struct ehci_softc *)bus;
1138:
1139: #ifdef DIAGNOSTIC
1140: if (xfer->busy_free != XFER_BUSY) {
1141: printf("ehci_freex: xfer=%p not busy, 0x%08x\n", xfer,
1142: xfer->busy_free);
1143: return;
1144: }
1145: xfer->busy_free = XFER_FREE;
1146: if (!EXFER(xfer)->isdone) {
1147: printf("ehci_freex: !isdone\n");
1148: return;
1149: }
1150: #endif
1151: SIMPLEQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next);
1152: }
1153:
1154: void
1155: ehci_device_clear_toggle(usbd_pipe_handle pipe)
1156: {
1157: struct ehci_pipe *epipe = (struct ehci_pipe *)pipe;
1158:
1159: DPRINTF(("ehci_device_clear_toggle: epipe=%p status=0x%x\n",
1160: epipe, epipe->sqh->qh.qh_qtd.qtd_status));
1161: #ifdef USB_DEBUG
1162: if (ehcidebug)
1163: usbd_dump_pipe(pipe);
1164: #endif
1165: #ifdef DIAGNOSTIC
1166: if ((epipe->sqh->qh.qh_qtd.qtd_status & htole32(EHCI_QTD_ACTIVE)) != 0)
1167: panic("ehci_device_clear_toggle: queue active");
1168: #endif
1169: epipe->sqh->qh.qh_qtd.qtd_status &= htole32(~EHCI_QTD_TOGGLE_MASK);
1170: }
1171:
1172: void
1173: ehci_noop(usbd_pipe_handle pipe)
1174: {
1175: }
1176:
1177: #ifdef EHCI_DEBUG
1178: void
1179: ehci_dump_regs(ehci_softc_t *sc)
1180: {
1181: int i;
1182:
1183: printf("cmd=0x%08x, sts=0x%08x, ien=0x%08x\n",
1184: EOREAD4(sc, EHCI_USBCMD),
1185: EOREAD4(sc, EHCI_USBSTS),
1186: EOREAD4(sc, EHCI_USBINTR));
1187: printf("frindex=0x%08x ctrdsegm=0x%08x periodic=0x%08x async=0x%08x\n",
1188: EOREAD4(sc, EHCI_FRINDEX),
1189: EOREAD4(sc, EHCI_CTRLDSSEGMENT),
1190: EOREAD4(sc, EHCI_PERIODICLISTBASE),
1191: EOREAD4(sc, EHCI_ASYNCLISTADDR));
1192: for (i = 1; i <= sc->sc_noport; i++)
1193: printf("port %d status=0x%08x\n", i,
1194: EOREAD4(sc, EHCI_PORTSC(i)));
1195: }
1196:
1197: /*
1198: * Unused function - this is meant to be called from a kernel
1199: * debugger.
1200: */
1201: void
1202: ehci_dump()
1203: {
1204: ehci_dump_regs(theehci);
1205: }
1206:
1207: void
1208: ehci_dump_link(ehci_link_t link, int type)
1209: {
1210: link = letoh32(link);
1211: printf("0x%08x", link);
1212: if (link & EHCI_LINK_TERMINATE)
1213: printf("<T>");
1214: else {
1215: printf("<");
1216: if (type) {
1217: switch (EHCI_LINK_TYPE(link)) {
1218: case EHCI_LINK_ITD: printf("ITD"); break;
1219: case EHCI_LINK_QH: printf("QH"); break;
1220: case EHCI_LINK_SITD: printf("SITD"); break;
1221: case EHCI_LINK_FSTN: printf("FSTN"); break;
1222: }
1223: }
1224: printf(">");
1225: }
1226: }
1227:
1228: void
1229: ehci_dump_sqtds(ehci_soft_qtd_t *sqtd)
1230: {
1231: int i;
1232: u_int32_t stop;
1233:
1234: stop = 0;
1235: for (i = 0; sqtd && i < 20 && !stop; sqtd = sqtd->nextqtd, i++) {
1236: ehci_dump_sqtd(sqtd);
1237: stop = sqtd->qtd.qtd_next & htole32(EHCI_LINK_TERMINATE);
1238: }
1239: if (!stop)
1240: printf("dump aborted, too many TDs\n");
1241: }
1242:
1243: void
1244: ehci_dump_sqtd(ehci_soft_qtd_t *sqtd)
1245: {
1246: printf("QTD(%p) at 0x%08x:\n", sqtd, sqtd->physaddr);
1247: ehci_dump_qtd(&sqtd->qtd);
1248: }
1249:
1250: void
1251: ehci_dump_qtd(ehci_qtd_t *qtd)
1252: {
1253: u_int32_t s;
1254: char sbuf[128];
1255:
1256: printf(" next="); ehci_dump_link(qtd->qtd_next, 0);
1257: printf(" altnext="); ehci_dump_link(qtd->qtd_altnext, 0);
1258: printf("\n");
1259: s = letoh32(qtd->qtd_status);
1260: bitmask_snprintf(EHCI_QTD_GET_STATUS(s), "\20\10ACTIVE\7HALTED"
1261: "\6BUFERR\5BABBLE\4XACTERR\3MISSED\2SPLIT\1PING",
1262: sbuf, sizeof(sbuf));
1263: printf(" status=0x%08x: toggle=%d bytes=0x%x ioc=%d c_page=0x%x\n",
1264: s, EHCI_QTD_GET_TOGGLE(s), EHCI_QTD_GET_BYTES(s),
1265: EHCI_QTD_GET_IOC(s), EHCI_QTD_GET_C_PAGE(s));
1266: printf(" cerr=%d pid=%d stat=0x%s\n", EHCI_QTD_GET_CERR(s),
1267: EHCI_QTD_GET_PID(s), sbuf);
1268: for (s = 0; s < 5; s++)
1269: printf(" buffer[%d]=0x%08x\n", s, letoh32(qtd->qtd_buffer[s]));
1270: }
1271:
1272: void
1273: ehci_dump_sqh(ehci_soft_qh_t *sqh)
1274: {
1275: ehci_qh_t *qh = &sqh->qh;
1276: u_int32_t endp, endphub;
1277:
1278: printf("QH(%p) at 0x%08x:\n", sqh, sqh->physaddr);
1279: printf(" link="); ehci_dump_link(qh->qh_link, 1); printf("\n");
1280: endp = letoh32(qh->qh_endp);
1281: printf(" endp=0x%08x\n", endp);
1282: printf(" addr=0x%02x inact=%d endpt=%d eps=%d dtc=%d hrecl=%d\n",
1283: EHCI_QH_GET_ADDR(endp), EHCI_QH_GET_INACT(endp),
1284: EHCI_QH_GET_ENDPT(endp), EHCI_QH_GET_EPS(endp),
1285: EHCI_QH_GET_DTC(endp), EHCI_QH_GET_HRECL(endp));
1286: printf(" mpl=0x%x ctl=%d nrl=%d\n",
1287: EHCI_QH_GET_MPL(endp), EHCI_QH_GET_CTL(endp),
1288: EHCI_QH_GET_NRL(endp));
1289: endphub = letoh32(qh->qh_endphub);
1290: printf(" endphub=0x%08x\n", endphub);
1291: printf(" smask=0x%02x cmask=0x%02x huba=0x%02x port=%d mult=%d\n",
1292: EHCI_QH_GET_SMASK(endphub), EHCI_QH_GET_CMASK(endphub),
1293: EHCI_QH_GET_HUBA(endphub), EHCI_QH_GET_PORT(endphub),
1294: EHCI_QH_GET_MULT(endphub));
1295: printf(" curqtd="); ehci_dump_link(qh->qh_curqtd, 0); printf("\n");
1296: printf("Overlay qTD:\n");
1297: ehci_dump_qtd(&qh->qh_qtd);
1298: }
1299:
1300: #ifdef DIAGNOSTIC
1301: void
1302: ehci_dump_exfer(struct ehci_xfer *ex)
1303: {
1304: printf("ehci_dump_exfer: ex=%p\n", ex);
1305: }
1306: #endif
1307: #endif /* EHCI_DEBUG */
1308:
1309: usbd_status
1310: ehci_open(usbd_pipe_handle pipe)
1311: {
1312: usbd_device_handle dev = pipe->device;
1313: ehci_softc_t *sc = (ehci_softc_t *)dev->bus;
1314: usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc;
1315: u_int8_t addr = dev->address;
1316: u_int8_t xfertype = ed->bmAttributes & UE_XFERTYPE;
1317: struct ehci_pipe *epipe = (struct ehci_pipe *)pipe;
1318: ehci_soft_qh_t *sqh;
1319: usbd_status err;
1320: int s;
1321: int ival, speed, naks;
1322: int hshubaddr, hshubport;
1323:
1324: DPRINTFN(1, ("ehci_open: pipe=%p, addr=%d, endpt=%d (%d)\n",
1325: pipe, addr, ed->bEndpointAddress, sc->sc_addr));
1326:
1327: if (sc->sc_dying)
1328: return (USBD_IOERROR);
1329:
1330: if (dev->myhsport) {
1331: hshubaddr = dev->myhsport->parent->address;
1332: hshubport = dev->myhsport->portno;
1333: } else {
1334: hshubaddr = 0;
1335: hshubport = 0;
1336: }
1337:
1338: if (addr == sc->sc_addr) {
1339: switch (ed->bEndpointAddress) {
1340: case USB_CONTROL_ENDPOINT:
1341: pipe->methods = &ehci_root_ctrl_methods;
1342: break;
1343: case UE_DIR_IN | EHCI_INTR_ENDPT:
1344: pipe->methods = &ehci_root_intr_methods;
1345: break;
1346: default:
1347: return (USBD_INVAL);
1348: }
1349: return (USBD_NORMAL_COMPLETION);
1350: }
1351:
1352: /* XXX All this stuff is only valid for async. */
1353: switch (dev->speed) {
1354: case USB_SPEED_LOW: speed = EHCI_QH_SPEED_LOW; break;
1355: case USB_SPEED_FULL: speed = EHCI_QH_SPEED_FULL; break;
1356: case USB_SPEED_HIGH: speed = EHCI_QH_SPEED_HIGH; break;
1357: default: panic("ehci_open: bad device speed %d", dev->speed);
1358: }
1359: if (speed != EHCI_QH_SPEED_HIGH && xfertype == UE_ISOCHRONOUS) {
1360: printf("%s: *** WARNING: opening low/full speed isochronous "
1361: "device, this does not work yet.\n",
1362: sc->sc_bus.bdev.dv_xname);
1363: DPRINTFN(1,("ehci_open: hshubaddr=%d hshubport=%d\n",
1364: hshubaddr, hshubport));
1365: return (USBD_INVAL);
1366: }
1367:
1368: naks = 8; /* XXX */
1369: sqh = ehci_alloc_sqh(sc);
1370: if (sqh == NULL)
1371: goto bad0;
1372: /* qh_link filled when the QH is added */
1373: sqh->qh.qh_endp = htole32(
1374: EHCI_QH_SET_ADDR(addr) |
1375: EHCI_QH_SET_ENDPT(UE_GET_ADDR(ed->bEndpointAddress)) |
1376: EHCI_QH_SET_EPS(speed) |
1377: (xfertype == UE_CONTROL ? EHCI_QH_DTC : 0) |
1378: EHCI_QH_SET_MPL(UGETW(ed->wMaxPacketSize)) |
1379: (speed != EHCI_QH_SPEED_HIGH && xfertype == UE_CONTROL ?
1380: EHCI_QH_CTL : 0) |
1381: EHCI_QH_SET_NRL(naks));
1382: sqh->qh.qh_endphub = htole32(
1383: EHCI_QH_SET_MULT(1) |
1384: EHCI_QH_SET_HUBA(hshubaddr) |
1385: EHCI_QH_SET_PORT(hshubport) |
1386: EHCI_QH_SET_CMASK(0x1c) | /* XXX */
1387: EHCI_QH_SET_SMASK(xfertype == UE_INTERRUPT ? 0x01 : 0));
1388: sqh->qh.qh_curqtd = EHCI_NULL;
1389: /* Fill the overlay qTD */
1390: sqh->qh.qh_qtd.qtd_next = EHCI_NULL;
1391: sqh->qh.qh_qtd.qtd_altnext = EHCI_NULL;
1392: sqh->qh.qh_qtd.qtd_status =
1393: htole32(EHCI_QTD_SET_TOGGLE(pipe->endpoint->savedtoggle));
1394:
1395: epipe->sqh = sqh;
1396:
1397: switch (xfertype) {
1398: case UE_CONTROL:
1399: err = usb_allocmem(&sc->sc_bus, sizeof(usb_device_request_t),
1400: 0, &epipe->u.ctl.reqdma);
1401: #ifdef EHCI_DEBUG
1402: if (err)
1403: printf("ehci_open: usb_allocmem()=%d\n", err);
1404: #endif
1405: if (err)
1406: goto bad1;
1407: pipe->methods = &ehci_device_ctrl_methods;
1408: s = splusb();
1409: ehci_add_qh(sqh, sc->sc_async_head);
1410: splx(s);
1411: break;
1412: case UE_BULK:
1413: pipe->methods = &ehci_device_bulk_methods;
1414: s = splusb();
1415: ehci_add_qh(sqh, sc->sc_async_head);
1416: splx(s);
1417: break;
1418: case UE_INTERRUPT:
1419: pipe->methods = &ehci_device_intr_methods;
1420: ival = pipe->interval;
1421: if (ival == USBD_DEFAULT_INTERVAL)
1422: ival = ed->bInterval;
1423: return (ehci_device_setintr(sc, sqh, ival));
1424: case UE_ISOCHRONOUS:
1425: pipe->methods = &ehci_device_isoc_methods;
1426: return (USBD_INVAL);
1427: default:
1428: return (USBD_INVAL);
1429: }
1430: return (USBD_NORMAL_COMPLETION);
1431:
1432: bad1:
1433: ehci_free_sqh(sc, sqh);
1434: bad0:
1435: return (USBD_NOMEM);
1436: }
1437:
1438: /*
1439: * Add an ED to the schedule. Called at splusb().
1440: * If in the async schedule, it will always have a next.
1441: * If in the intr schedule it may not.
1442: */
1443: void
1444: ehci_add_qh(ehci_soft_qh_t *sqh, ehci_soft_qh_t *head)
1445: {
1446: SPLUSBCHECK;
1447:
1448: sqh->next = head->next;
1449: sqh->prev = head;
1450: sqh->qh.qh_link = head->qh.qh_link;
1451: head->next = sqh;
1452: if (sqh->next)
1453: sqh->next->prev = sqh;
1454: head->qh.qh_link = htole32(sqh->physaddr | EHCI_LINK_QH);
1455:
1456: #ifdef EHCI_DEBUG
1457: if (ehcidebug > 5) {
1458: printf("ehci_add_qh:\n");
1459: ehci_dump_sqh(sqh);
1460: }
1461: #endif
1462: }
1463:
1464: /*
1465: * Remove an ED from the schedule. Called at splusb().
1466: * Will always have a 'next' if it's in the async list as it's circular.
1467: */
1468: void
1469: ehci_rem_qh(ehci_softc_t *sc, ehci_soft_qh_t *sqh, ehci_soft_qh_t *head)
1470: {
1471: SPLUSBCHECK;
1472: /* XXX */
1473: sqh->prev->qh.qh_link = sqh->qh.qh_link;
1474: sqh->prev->next = sqh->next;
1475: if (sqh->next)
1476: sqh->next->prev = sqh->prev;
1477: ehci_sync_hc(sc);
1478: }
1479:
1480: void
1481: ehci_set_qh_qtd(ehci_soft_qh_t *sqh, ehci_soft_qtd_t *sqtd)
1482: {
1483: int i;
1484: u_int32_t status;
1485:
1486: /* Save toggle bit and ping status. */
1487: status = sqh->qh.qh_qtd.qtd_status &
1488: htole32(EHCI_QTD_TOGGLE_MASK |
1489: EHCI_QTD_SET_STATUS(EHCI_QTD_PINGSTATE));
1490: /* Set HALTED to make hw leave it alone. */
1491: sqh->qh.qh_qtd.qtd_status =
1492: htole32(EHCI_QTD_SET_STATUS(EHCI_QTD_HALTED));
1493: sqh->qh.qh_curqtd = 0;
1494: sqh->qh.qh_qtd.qtd_next = htole32(sqtd->physaddr);
1495: sqh->qh.qh_qtd.qtd_altnext = EHCI_NULL;
1496: for (i = 0; i < EHCI_QTD_NBUFFERS; i++)
1497: sqh->qh.qh_qtd.qtd_buffer[i] = 0;
1498: sqh->sqtd = sqtd;
1499: /* Set !HALTED && !ACTIVE to start execution, preserve some fields */
1500: sqh->qh.qh_qtd.qtd_status = status;
1501: }
1502:
1503: /*
1504: * Ensure that the HC has released all references to the QH. We do this
1505: * by asking for a Async Advance Doorbell interrupt and then we wait for
1506: * the interrupt.
1507: * To make this easier we first obtain exclusive use of the doorbell.
1508: */
1509: void
1510: ehci_sync_hc(ehci_softc_t *sc)
1511: {
1512: int s, error;
1513: int tries = 0;
1514:
1515: if (sc->sc_dying) {
1516: DPRINTFN(2,("ehci_sync_hc: dying\n"));
1517: return;
1518: }
1519: DPRINTFN(2,("ehci_sync_hc: enter\n"));
1520: /* get doorbell */
1521: rw_enter_write(&sc->sc_doorbell_lock);
1522: s = splhardusb();
1523: do {
1524: /* ask for doorbell */
1525: EOWRITE4(sc, EHCI_USBCMD, EOREAD4(sc, EHCI_USBCMD) |
1526: EHCI_CMD_IAAD);
1527: DPRINTFN(1,("ehci_sync_hc: cmd=0x%08x sts=0x%08x\n",
1528: EOREAD4(sc, EHCI_USBCMD), EOREAD4(sc, EHCI_USBSTS)));
1529: /* bell wait */
1530: error = tsleep(&sc->sc_async_head, PZERO, "ehcidi", hz / 2);
1531: DPRINTFN(1,("ehci_sync_hc: cmd=0x%08x sts=0x%08x\n",
1532: EOREAD4(sc, EHCI_USBCMD), EOREAD4(sc, EHCI_USBSTS)));
1533: } while (error && ++tries < 10);
1534: splx(s);
1535: /* release doorbell */
1536: rw_exit_write(&sc->sc_doorbell_lock);
1537: #ifdef DIAGNOSTIC
1538: if (error)
1539: printf("ehci_sync_hc: tsleep() = %d\n", error);
1540: #endif
1541: DPRINTFN(2,("ehci_sync_hc: exit\n"));
1542: }
1543:
1544: /***********/
1545:
1546: /*
1547: * Data structures and routines to emulate the root hub.
1548: */
1549: usb_device_descriptor_t ehci_devd = {
1550: USB_DEVICE_DESCRIPTOR_SIZE,
1551: UDESC_DEVICE, /* type */
1552: {0x00, 0x02}, /* USB version */
1553: UDCLASS_HUB, /* class */
1554: UDSUBCLASS_HUB, /* subclass */
1555: UDPROTO_HSHUBSTT, /* protocol */
1556: 64, /* max packet */
1557: {0},{0},{0x00,0x01}, /* device id */
1558: 1,2,0, /* string indicies */
1559: 1 /* # of configurations */
1560: };
1561:
1562: usb_device_qualifier_t ehci_odevd = {
1563: USB_DEVICE_DESCRIPTOR_SIZE,
1564: UDESC_DEVICE_QUALIFIER, /* type */
1565: {0x00, 0x02}, /* USB version */
1566: UDCLASS_HUB, /* class */
1567: UDSUBCLASS_HUB, /* subclass */
1568: UDPROTO_FSHUB, /* protocol */
1569: 64, /* max packet */
1570: 1, /* # of configurations */
1571: 0
1572: };
1573:
1574: usb_config_descriptor_t ehci_confd = {
1575: USB_CONFIG_DESCRIPTOR_SIZE,
1576: UDESC_CONFIG,
1577: {USB_CONFIG_DESCRIPTOR_SIZE +
1578: USB_INTERFACE_DESCRIPTOR_SIZE +
1579: USB_ENDPOINT_DESCRIPTOR_SIZE},
1580: 1,
1581: 1,
1582: 0,
1583: UC_SELF_POWERED,
1584: 0 /* max power */
1585: };
1586:
1587: usb_interface_descriptor_t ehci_ifcd = {
1588: USB_INTERFACE_DESCRIPTOR_SIZE,
1589: UDESC_INTERFACE,
1590: 0,
1591: 0,
1592: 1,
1593: UICLASS_HUB,
1594: UISUBCLASS_HUB,
1595: UIPROTO_HSHUBSTT,
1596: 0
1597: };
1598:
1599: usb_endpoint_descriptor_t ehci_endpd = {
1600: USB_ENDPOINT_DESCRIPTOR_SIZE,
1601: UDESC_ENDPOINT,
1602: UE_DIR_IN | EHCI_INTR_ENDPT,
1603: UE_INTERRUPT,
1604: {8, 0}, /* max packet */
1605: 255
1606: };
1607:
1608: usb_hub_descriptor_t ehci_hubd = {
1609: USB_HUB_DESCRIPTOR_SIZE,
1610: UDESC_HUB,
1611: 0,
1612: {0,0},
1613: 0,
1614: 0,
1615: {0},
1616: };
1617:
1618: int
1619: ehci_str(usb_string_descriptor_t *p, int l, const char *s)
1620: {
1621: int i;
1622:
1623: if (l == 0)
1624: return (0);
1625: p->bLength = 2 * strlen(s) + 2;
1626: if (l == 1)
1627: return (1);
1628: p->bDescriptorType = UDESC_STRING;
1629: l -= 2;
1630: for (i = 0; s[i] && l > 1; i++, l -= 2)
1631: USETW2(p->bString[i], 0, s[i]);
1632: return (2*i+2);
1633: }
1634:
1635: /*
1636: * Simulate a hardware hub by handling all the necessary requests.
1637: */
1638: usbd_status
1639: ehci_root_ctrl_transfer(usbd_xfer_handle xfer)
1640: {
1641: usbd_status err;
1642:
1643: /* Insert last in queue. */
1644: err = usb_insert_transfer(xfer);
1645: if (err)
1646: return (err);
1647:
1648: /* Pipe isn't running, start first */
1649: return (ehci_root_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
1650: }
1651:
1652: usbd_status
1653: ehci_root_ctrl_start(usbd_xfer_handle xfer)
1654: {
1655: ehci_softc_t *sc = (ehci_softc_t *)xfer->pipe->device->bus;
1656: usb_device_request_t *req;
1657: void *buf = NULL;
1658: int port, i;
1659: int s, len, value, index, l, totlen = 0;
1660: usb_port_status_t ps;
1661: usb_hub_descriptor_t hubd;
1662: usbd_status err;
1663: u_int32_t v;
1664:
1665: if (sc->sc_dying)
1666: return (USBD_IOERROR);
1667:
1668: #ifdef DIAGNOSTIC
1669: if (!(xfer->rqflags & URQ_REQUEST))
1670: /* XXX panic */
1671: return (USBD_INVAL);
1672: #endif
1673: req = &xfer->request;
1674:
1675: DPRINTFN(4,("ehci_root_ctrl_start: type=0x%02x request=%02x\n",
1676: req->bmRequestType, req->bRequest));
1677:
1678: len = UGETW(req->wLength);
1679: value = UGETW(req->wValue);
1680: index = UGETW(req->wIndex);
1681:
1682: if (len != 0)
1683: buf = KERNADDR(&xfer->dmabuf, 0);
1684:
1685: #define C(x,y) ((x) | ((y) << 8))
1686: switch(C(req->bRequest, req->bmRequestType)) {
1687: case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE):
1688: case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE):
1689: case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT):
1690: /*
1691: * DEVICE_REMOTE_WAKEUP and ENDPOINT_HALT are no-ops
1692: * for the integrated root hub.
1693: */
1694: break;
1695: case C(UR_GET_CONFIG, UT_READ_DEVICE):
1696: if (len > 0) {
1697: *(u_int8_t *)buf = sc->sc_conf;
1698: totlen = 1;
1699: }
1700: break;
1701: case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
1702: DPRINTFN(8,("ehci_root_ctrl_start: wValue=0x%04x\n", value));
1703: switch(value >> 8) {
1704: case UDESC_DEVICE:
1705: if ((value & 0xff) != 0) {
1706: err = USBD_IOERROR;
1707: goto ret;
1708: }
1709: totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE);
1710: USETW(ehci_devd.idVendor, sc->sc_id_vendor);
1711: memcpy(buf, &ehci_devd, l);
1712: break;
1713: /*
1714: * We can't really operate at another speed, but the spec says
1715: * we need this descriptor.
1716: */
1717: case UDESC_DEVICE_QUALIFIER:
1718: if ((value & 0xff) != 0) {
1719: err = USBD_IOERROR;
1720: goto ret;
1721: }
1722: totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE);
1723: memcpy(buf, &ehci_odevd, l);
1724: break;
1725: /*
1726: * We can't really operate at another speed, but the spec says
1727: * we need this descriptor.
1728: */
1729: case UDESC_OTHER_SPEED_CONFIGURATION:
1730: case UDESC_CONFIG:
1731: if ((value & 0xff) != 0) {
1732: err = USBD_IOERROR;
1733: goto ret;
1734: }
1735: totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE);
1736: memcpy(buf, &ehci_confd, l);
1737: ((usb_config_descriptor_t *)buf)->bDescriptorType =
1738: value >> 8;
1739: buf = (char *)buf + l;
1740: len -= l;
1741: l = min(len, USB_INTERFACE_DESCRIPTOR_SIZE);
1742: totlen += l;
1743: memcpy(buf, &ehci_ifcd, l);
1744: buf = (char *)buf + l;
1745: len -= l;
1746: l = min(len, USB_ENDPOINT_DESCRIPTOR_SIZE);
1747: totlen += l;
1748: memcpy(buf, &ehci_endpd, l);
1749: break;
1750: case UDESC_STRING:
1751: if (len == 0)
1752: break;
1753: *(u_int8_t *)buf = 0;
1754: totlen = 1;
1755: switch (value & 0xff) {
1756: case 0: /* Language table */
1757: totlen = ehci_str(buf, len, "\001");
1758: break;
1759: case 1: /* Vendor */
1760: totlen = ehci_str(buf, len, sc->sc_vendor);
1761: break;
1762: case 2: /* Product */
1763: totlen = ehci_str(buf, len, "EHCI root hub");
1764: break;
1765: }
1766: break;
1767: default:
1768: err = USBD_IOERROR;
1769: goto ret;
1770: }
1771: break;
1772: case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
1773: if (len > 0) {
1774: *(u_int8_t *)buf = 0;
1775: totlen = 1;
1776: }
1777: break;
1778: case C(UR_GET_STATUS, UT_READ_DEVICE):
1779: if (len > 1) {
1780: USETW(((usb_status_t *)buf)->wStatus,UDS_SELF_POWERED);
1781: totlen = 2;
1782: }
1783: break;
1784: case C(UR_GET_STATUS, UT_READ_INTERFACE):
1785: case C(UR_GET_STATUS, UT_READ_ENDPOINT):
1786: if (len > 1) {
1787: USETW(((usb_status_t *)buf)->wStatus, 0);
1788: totlen = 2;
1789: }
1790: break;
1791: case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
1792: if (value >= USB_MAX_DEVICES) {
1793: err = USBD_IOERROR;
1794: goto ret;
1795: }
1796: sc->sc_addr = value;
1797: break;
1798: case C(UR_SET_CONFIG, UT_WRITE_DEVICE):
1799: if (value != 0 && value != 1) {
1800: err = USBD_IOERROR;
1801: goto ret;
1802: }
1803: sc->sc_conf = value;
1804: break;
1805: case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE):
1806: break;
1807: case C(UR_SET_FEATURE, UT_WRITE_DEVICE):
1808: case C(UR_SET_FEATURE, UT_WRITE_INTERFACE):
1809: case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
1810: err = USBD_IOERROR;
1811: goto ret;
1812: case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
1813: break;
1814: case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT):
1815: break;
1816: /* Hub requests */
1817: case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE):
1818: break;
1819: case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER):
1820: DPRINTFN(8, ("ehci_root_ctrl_start: UR_CLEAR_PORT_FEATURE "
1821: "port=%d feature=%d\n", index, value));
1822: if (index < 1 || index > sc->sc_noport) {
1823: err = USBD_IOERROR;
1824: goto ret;
1825: }
1826: port = EHCI_PORTSC(index);
1827: v = EOREAD4(sc, port) &~ EHCI_PS_CLEAR;
1828: switch(value) {
1829: case UHF_PORT_ENABLE:
1830: EOWRITE4(sc, port, v &~ EHCI_PS_PE);
1831: break;
1832: case UHF_PORT_SUSPEND:
1833: EOWRITE4(sc, port, v &~ EHCI_PS_SUSP);
1834: break;
1835: case UHF_PORT_POWER:
1836: EOWRITE4(sc, port, v &~ EHCI_PS_PP);
1837: break;
1838: case UHF_PORT_TEST:
1839: DPRINTFN(2,("ehci_root_ctrl_start: "
1840: "clear port test %d\n", index));
1841: break;
1842: case UHF_PORT_INDICATOR:
1843: DPRINTFN(2,("ehci_root_ctrl_start: "
1844: "clear port index %d\n", index));
1845: EOWRITE4(sc, port, v &~ EHCI_PS_PIC);
1846: break;
1847: case UHF_C_PORT_CONNECTION:
1848: EOWRITE4(sc, port, v | EHCI_PS_CSC);
1849: break;
1850: case UHF_C_PORT_ENABLE:
1851: EOWRITE4(sc, port, v | EHCI_PS_PEC);
1852: break;
1853: case UHF_C_PORT_SUSPEND:
1854: /* how? */
1855: break;
1856: case UHF_C_PORT_OVER_CURRENT:
1857: EOWRITE4(sc, port, v | EHCI_PS_OCC);
1858: break;
1859: case UHF_C_PORT_RESET:
1860: sc->sc_isreset = 0;
1861: break;
1862: default:
1863: err = USBD_IOERROR;
1864: goto ret;
1865: }
1866: #if 0
1867: switch(value) {
1868: case UHF_C_PORT_CONNECTION:
1869: case UHF_C_PORT_ENABLE:
1870: case UHF_C_PORT_SUSPEND:
1871: case UHF_C_PORT_OVER_CURRENT:
1872: case UHF_C_PORT_RESET:
1873: /* Enable RHSC interrupt if condition is cleared. */
1874: if ((OREAD4(sc, port) >> 16) == 0)
1875: ehci_pcd_able(sc, 1);
1876: break;
1877: default:
1878: break;
1879: }
1880: #endif
1881: break;
1882: case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
1883: if ((value & 0xff) != 0) {
1884: err = USBD_IOERROR;
1885: goto ret;
1886: }
1887: hubd = ehci_hubd;
1888: hubd.bNbrPorts = sc->sc_noport;
1889: v = EOREAD4(sc, EHCI_HCSPARAMS);
1890: USETW(hubd.wHubCharacteristics,
1891: EHCI_HCS_PPC(v) ? UHD_PWR_INDIVIDUAL : UHD_PWR_NO_SWITCH |
1892: EHCI_HCS_P_INDICATOR(EREAD4(sc, EHCI_HCSPARAMS))
1893: ? UHD_PORT_IND : 0);
1894: hubd.bPwrOn2PwrGood = 200; /* XXX can't find out? */
1895: for (i = 0, l = sc->sc_noport; l > 0; i++, l -= 8, v >>= 8)
1896: hubd.DeviceRemovable[i++] = 0; /* XXX can't find out? */
1897: hubd.bDescLength = USB_HUB_DESCRIPTOR_SIZE + i;
1898: l = min(len, hubd.bDescLength);
1899: totlen = l;
1900: memcpy(buf, &hubd, l);
1901: break;
1902: case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
1903: if (len != 4) {
1904: err = USBD_IOERROR;
1905: goto ret;
1906: }
1907: memset(buf, 0, len); /* ? XXX */
1908: totlen = len;
1909: break;
1910: case C(UR_GET_STATUS, UT_READ_CLASS_OTHER):
1911: DPRINTFN(8,("ehci_root_ctrl_start: get port status i=%d\n",
1912: index));
1913: if (index < 1 || index > sc->sc_noport) {
1914: err = USBD_IOERROR;
1915: goto ret;
1916: }
1917: if (len != 4) {
1918: err = USBD_IOERROR;
1919: goto ret;
1920: }
1921: v = EOREAD4(sc, EHCI_PORTSC(index));
1922: DPRINTFN(8,("ehci_root_ctrl_start: port status=0x%04x\n", v));
1923: i = UPS_HIGH_SPEED;
1924: if (v & EHCI_PS_CS) i |= UPS_CURRENT_CONNECT_STATUS;
1925: if (v & EHCI_PS_PE) i |= UPS_PORT_ENABLED;
1926: if (v & EHCI_PS_SUSP) i |= UPS_SUSPEND;
1927: if (v & EHCI_PS_OCA) i |= UPS_OVERCURRENT_INDICATOR;
1928: if (v & EHCI_PS_PR) i |= UPS_RESET;
1929: if (v & EHCI_PS_PP) i |= UPS_PORT_POWER;
1930: USETW(ps.wPortStatus, i);
1931: i = 0;
1932: if (v & EHCI_PS_CSC) i |= UPS_C_CONNECT_STATUS;
1933: if (v & EHCI_PS_PEC) i |= UPS_C_PORT_ENABLED;
1934: if (v & EHCI_PS_OCC) i |= UPS_C_OVERCURRENT_INDICATOR;
1935: if (sc->sc_isreset) i |= UPS_C_PORT_RESET;
1936: USETW(ps.wPortChange, i);
1937: l = min(len, sizeof(ps));
1938: memcpy(buf, &ps, l);
1939: totlen = l;
1940: break;
1941: case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
1942: err = USBD_IOERROR;
1943: goto ret;
1944: case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE):
1945: break;
1946: case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER):
1947: if (index < 1 || index > sc->sc_noport) {
1948: err = USBD_IOERROR;
1949: goto ret;
1950: }
1951: port = EHCI_PORTSC(index);
1952: v = EOREAD4(sc, port) &~ EHCI_PS_CLEAR;
1953: switch(value) {
1954: case UHF_PORT_ENABLE:
1955: EOWRITE4(sc, port, v | EHCI_PS_PE);
1956: break;
1957: case UHF_PORT_SUSPEND:
1958: EOWRITE4(sc, port, v | EHCI_PS_SUSP);
1959: break;
1960: case UHF_PORT_RESET:
1961: DPRINTFN(5,("ehci_root_ctrl_start: reset port %d\n",
1962: index));
1963: if (EHCI_PS_IS_LOWSPEED(v)) {
1964: /* Low speed device, give up ownership. */
1965: ehci_disown(sc, index, 1);
1966: break;
1967: }
1968: /* Start reset sequence. */
1969: v &= ~ (EHCI_PS_PE | EHCI_PS_PR);
1970: EOWRITE4(sc, port, v | EHCI_PS_PR);
1971: /* Wait for reset to complete. */
1972: usb_delay_ms(&sc->sc_bus, USB_PORT_ROOT_RESET_DELAY);
1973: if (sc->sc_dying) {
1974: err = USBD_IOERROR;
1975: goto ret;
1976: }
1977: /* Terminate reset sequence. */
1978: EOWRITE4(sc, port, v);
1979: /* Wait for HC to complete reset. */
1980: usb_delay_ms(&sc->sc_bus, EHCI_PORT_RESET_COMPLETE);
1981: if (sc->sc_dying) {
1982: err = USBD_IOERROR;
1983: goto ret;
1984: }
1985: v = EOREAD4(sc, port);
1986: DPRINTF(("ehci after reset, status=0x%08x\n", v));
1987: if (v & EHCI_PS_PR) {
1988: printf("%s: port reset timeout\n",
1989: sc->sc_bus.bdev.dv_xname);
1990: return (USBD_TIMEOUT);
1991: }
1992: if (!(v & EHCI_PS_PE)) {
1993: /* Not a high speed device, give up ownership.*/
1994: ehci_disown(sc, index, 0);
1995: break;
1996: }
1997: sc->sc_isreset = 1;
1998: DPRINTF(("ehci port %d reset, status = 0x%08x\n",
1999: index, v));
2000: break;
2001: case UHF_PORT_POWER:
2002: DPRINTFN(2,("ehci_root_ctrl_start: "
2003: "set port power %d\n", index));
2004: EOWRITE4(sc, port, v | EHCI_PS_PP);
2005: break;
2006: case UHF_PORT_TEST:
2007: DPRINTFN(2,("ehci_root_ctrl_start: "
2008: "set port test %d\n", index));
2009: break;
2010: case UHF_PORT_INDICATOR:
2011: DPRINTFN(2,("ehci_root_ctrl_start: "
2012: "set port ind %d\n", index));
2013: EOWRITE4(sc, port, v | EHCI_PS_PIC);
2014: break;
2015: default:
2016: err = USBD_IOERROR;
2017: goto ret;
2018: }
2019: break;
2020: case C(UR_CLEAR_TT_BUFFER, UT_WRITE_CLASS_OTHER):
2021: case C(UR_RESET_TT, UT_WRITE_CLASS_OTHER):
2022: case C(UR_GET_TT_STATE, UT_READ_CLASS_OTHER):
2023: case C(UR_STOP_TT, UT_WRITE_CLASS_OTHER):
2024: break;
2025: default:
2026: err = USBD_IOERROR;
2027: goto ret;
2028: }
2029: xfer->actlen = totlen;
2030: err = USBD_NORMAL_COMPLETION;
2031: ret:
2032: xfer->status = err;
2033: s = splusb();
2034: usb_transfer_complete(xfer);
2035: splx(s);
2036: return (USBD_IN_PROGRESS);
2037: }
2038:
2039: void
2040: ehci_disown(ehci_softc_t *sc, int index, int lowspeed)
2041: {
2042: int port;
2043: u_int32_t v;
2044:
2045: DPRINTF(("ehci_disown: index=%d lowspeed=%d\n", index, lowspeed));
2046:
2047: port = EHCI_PORTSC(index);
2048: v = EOREAD4(sc, port) &~ EHCI_PS_CLEAR;
2049: EOWRITE4(sc, port, v | EHCI_PS_PO);
2050: }
2051:
2052: /* Abort a root control request. */
2053: void
2054: ehci_root_ctrl_abort(usbd_xfer_handle xfer)
2055: {
2056: /* Nothing to do, all transfers are synchronous. */
2057: }
2058:
2059: /* Close the root pipe. */
2060: void
2061: ehci_root_ctrl_close(usbd_pipe_handle pipe)
2062: {
2063: DPRINTF(("ehci_root_ctrl_close\n"));
2064: /* Nothing to do. */
2065: }
2066:
2067: void
2068: ehci_root_intr_done(usbd_xfer_handle xfer)
2069: {
2070: }
2071:
2072: usbd_status
2073: ehci_root_intr_transfer(usbd_xfer_handle xfer)
2074: {
2075: usbd_status err;
2076:
2077: /* Insert last in queue. */
2078: err = usb_insert_transfer(xfer);
2079: if (err)
2080: return (err);
2081:
2082: /* Pipe isn't running, start first */
2083: return (ehci_root_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
2084: }
2085:
2086: usbd_status
2087: ehci_root_intr_start(usbd_xfer_handle xfer)
2088: {
2089: usbd_pipe_handle pipe = xfer->pipe;
2090: ehci_softc_t *sc = (ehci_softc_t *)pipe->device->bus;
2091:
2092: if (sc->sc_dying)
2093: return (USBD_IOERROR);
2094:
2095: sc->sc_intrxfer = xfer;
2096:
2097: return (USBD_IN_PROGRESS);
2098: }
2099:
2100: /* Abort a root interrupt request. */
2101: void
2102: ehci_root_intr_abort(usbd_xfer_handle xfer)
2103: {
2104: int s;
2105:
2106: if (xfer->pipe->intrxfer == xfer) {
2107: DPRINTF(("ehci_root_intr_abort: remove\n"));
2108: xfer->pipe->intrxfer = NULL;
2109: }
2110: xfer->status = USBD_CANCELLED;
2111: s = splusb();
2112: usb_transfer_complete(xfer);
2113: splx(s);
2114: }
2115:
2116: /* Close the root pipe. */
2117: void
2118: ehci_root_intr_close(usbd_pipe_handle pipe)
2119: {
2120: ehci_softc_t *sc = (ehci_softc_t *)pipe->device->bus;
2121:
2122: DPRINTF(("ehci_root_intr_close\n"));
2123:
2124: sc->sc_intrxfer = NULL;
2125: }
2126:
2127: void
2128: ehci_root_ctrl_done(usbd_xfer_handle xfer)
2129: {
2130: }
2131:
2132: /************************/
2133:
2134: ehci_soft_qh_t *
2135: ehci_alloc_sqh(ehci_softc_t *sc)
2136: {
2137: ehci_soft_qh_t *sqh;
2138: usbd_status err;
2139: int i, offs;
2140: usb_dma_t dma;
2141:
2142: if (sc->sc_freeqhs == NULL) {
2143: DPRINTFN(2, ("ehci_alloc_sqh: allocating chunk\n"));
2144: err = usb_allocmem(&sc->sc_bus, EHCI_SQH_SIZE * EHCI_SQH_CHUNK,
2145: EHCI_PAGE_SIZE, &dma);
2146: #ifdef EHCI_DEBUG
2147: if (err)
2148: printf("ehci_alloc_sqh: usb_allocmem()=%d\n", err);
2149: #endif
2150: if (err)
2151: return (NULL);
2152: for(i = 0; i < EHCI_SQH_CHUNK; i++) {
2153: offs = i * EHCI_SQH_SIZE;
2154: sqh = KERNADDR(&dma, offs);
2155: sqh->physaddr = DMAADDR(&dma, offs);
2156: sqh->next = sc->sc_freeqhs;
2157: sc->sc_freeqhs = sqh;
2158: }
2159: }
2160: sqh = sc->sc_freeqhs;
2161: sc->sc_freeqhs = sqh->next;
2162: memset(&sqh->qh, 0, sizeof(ehci_qh_t));
2163: sqh->next = NULL;
2164: sqh->prev = NULL;
2165: return (sqh);
2166: }
2167:
2168: void
2169: ehci_free_sqh(ehci_softc_t *sc, ehci_soft_qh_t *sqh)
2170: {
2171: sqh->next = sc->sc_freeqhs;
2172: sc->sc_freeqhs = sqh;
2173: }
2174:
2175: ehci_soft_qtd_t *
2176: ehci_alloc_sqtd(ehci_softc_t *sc)
2177: {
2178: ehci_soft_qtd_t *sqtd;
2179: usbd_status err;
2180: int i, offs;
2181: usb_dma_t dma;
2182: int s;
2183:
2184: if (sc->sc_freeqtds == NULL) {
2185: DPRINTFN(2, ("ehci_alloc_sqtd: allocating chunk\n"));
2186: err = usb_allocmem(&sc->sc_bus, EHCI_SQTD_SIZE*EHCI_SQTD_CHUNK,
2187: EHCI_PAGE_SIZE, &dma);
2188: #ifdef EHCI_DEBUG
2189: if (err)
2190: printf("ehci_alloc_sqtd: usb_allocmem()=%d\n", err);
2191: #endif
2192: if (err)
2193: return (NULL);
2194: s = splusb();
2195: for(i = 0; i < EHCI_SQTD_CHUNK; i++) {
2196: offs = i * EHCI_SQTD_SIZE;
2197: sqtd = KERNADDR(&dma, offs);
2198: sqtd->physaddr = DMAADDR(&dma, offs);
2199: sqtd->nextqtd = sc->sc_freeqtds;
2200: sc->sc_freeqtds = sqtd;
2201: }
2202: splx(s);
2203: }
2204:
2205: s = splusb();
2206: sqtd = sc->sc_freeqtds;
2207: sc->sc_freeqtds = sqtd->nextqtd;
2208: memset(&sqtd->qtd, 0, sizeof(ehci_qtd_t));
2209: sqtd->nextqtd = NULL;
2210: sqtd->xfer = NULL;
2211: splx(s);
2212:
2213: return (sqtd);
2214: }
2215:
2216: void
2217: ehci_free_sqtd(ehci_softc_t *sc, ehci_soft_qtd_t *sqtd)
2218: {
2219: int s;
2220:
2221: s = splusb();
2222: sqtd->nextqtd = sc->sc_freeqtds;
2223: sc->sc_freeqtds = sqtd;
2224: splx(s);
2225: }
2226:
2227: usbd_status
2228: ehci_alloc_sqtd_chain(struct ehci_pipe *epipe, ehci_softc_t *sc, int alen,
2229: int rd, usbd_xfer_handle xfer, ehci_soft_qtd_t **sp, ehci_soft_qtd_t **ep)
2230: {
2231: ehci_soft_qtd_t *next, *cur;
2232: ehci_physaddr_t dataphys, dataphyspage, dataphyslastpage, nextphys;
2233: u_int32_t qtdstatus;
2234: int len, curlen, mps;
2235: int i, iscontrol, forceshort;
2236: usb_dma_t *dma = &xfer->dmabuf;
2237:
2238: DPRINTFN(alen<4*4096,("ehci_alloc_sqtd_chain: start len=%d\n", alen));
2239:
2240: len = alen;
2241: iscontrol = (epipe->pipe.endpoint->edesc->bmAttributes & UE_XFERTYPE) ==
2242: UE_CONTROL;
2243:
2244: dataphys = DMAADDR(dma, 0);
2245: dataphyslastpage = EHCI_PAGE(dataphys + len - 1);
2246: qtdstatus = EHCI_QTD_ACTIVE |
2247: EHCI_QTD_SET_PID(rd ? EHCI_QTD_PID_IN : EHCI_QTD_PID_OUT) |
2248: EHCI_QTD_SET_CERR(3); /* IOC and BYTES set below */
2249: mps = UGETW(epipe->pipe.endpoint->edesc->wMaxPacketSize);
2250: forceshort = ((xfer->flags & USBD_FORCE_SHORT_XFER) || len == 0) &&
2251: len % mps == 0;
2252: /*
2253: * The control transfer data stage always starts with a toggle of 1.
2254: * For other transfers we let the hardware track the toggle state.
2255: */
2256: if (iscontrol)
2257: qtdstatus |= EHCI_QTD_SET_TOGGLE(1);
2258:
2259: cur = ehci_alloc_sqtd(sc);
2260: *sp = cur;
2261: if (cur == NULL)
2262: goto nomem;
2263: for (;;) {
2264: dataphyspage = EHCI_PAGE(dataphys);
2265: /* The EHCI hardware can handle at most 5 pages. */
2266: if (dataphyslastpage - dataphyspage <
2267: EHCI_QTD_NBUFFERS * EHCI_PAGE_SIZE) {
2268: /* we can handle it in this QTD */
2269: curlen = len;
2270: } else {
2271: /* must use multiple TDs, fill as much as possible. */
2272: curlen = EHCI_QTD_NBUFFERS * EHCI_PAGE_SIZE -
2273: EHCI_PAGE_OFFSET(dataphys);
2274: #ifdef DIAGNOSTIC
2275: if (curlen > len) {
2276: printf("ehci_alloc_sqtd_chain: curlen=0x%x "
2277: "len=0x%x offs=0x%x\n", curlen, len,
2278: EHCI_PAGE_OFFSET(dataphys));
2279: printf("lastpage=0x%x page=0x%x phys=0x%x\n",
2280: dataphyslastpage, dataphyspage, dataphys);
2281: curlen = len;
2282: }
2283: #endif
2284: /* the length must be a multiple of the max size */
2285: curlen -= curlen % mps;
2286: DPRINTFN(1,("ehci_alloc_sqtd_chain: multiple QTDs, "
2287: "curlen=%d\n", curlen));
2288: #ifdef DIAGNOSTIC
2289: if (curlen == 0)
2290: panic("ehci_alloc_std: curlen == 0");
2291: #endif
2292: }
2293: DPRINTFN(4,("ehci_alloc_sqtd_chain: dataphys=0x%08x "
2294: "dataphyslastpage=0x%08x len=%d curlen=%d\n",
2295: dataphys, dataphyslastpage, len, curlen));
2296: len -= curlen;
2297:
2298: /*
2299: * Allocate another transfer if there's more data left,
2300: * or if force last short transfer flag is set and we're
2301: * allocating a multiple of the max packet size.
2302: */
2303: if (len != 0 || forceshort) {
2304: next = ehci_alloc_sqtd(sc);
2305: if (next == NULL)
2306: goto nomem;
2307: nextphys = htole32(next->physaddr);
2308: } else {
2309: next = NULL;
2310: nextphys = EHCI_NULL;
2311: }
2312:
2313: for (i = 0; i * EHCI_PAGE_SIZE <
2314: curlen + EHCI_PAGE_OFFSET(dataphys); i++) {
2315: ehci_physaddr_t a = dataphys + i * EHCI_PAGE_SIZE;
2316: if (i != 0) /* use offset only in first buffer */
2317: a = EHCI_PAGE(a);
2318: cur->qtd.qtd_buffer[i] = htole32(a);
2319: cur->qtd.qtd_buffer_hi[i] = 0;
2320: #ifdef DIAGNOSTIC
2321: if (i >= EHCI_QTD_NBUFFERS) {
2322: printf("ehci_alloc_sqtd_chain: i=%d\n", i);
2323: goto nomem;
2324: }
2325: #endif
2326: }
2327: cur->nextqtd = next;
2328: cur->qtd.qtd_next = cur->qtd.qtd_altnext = nextphys;
2329: cur->qtd.qtd_status = htole32(qtdstatus |
2330: EHCI_QTD_SET_BYTES(curlen));
2331: cur->xfer = xfer;
2332: cur->len = curlen;
2333: DPRINTFN(10,("ehci_alloc_sqtd_chain: cbp=0x%08x end=0x%08x\n",
2334: dataphys, dataphys + curlen));
2335: DPRINTFN(10,("ehci_alloc_sqtd_chain: curlen=%d\n", curlen));
2336: if (iscontrol) {
2337: /*
2338: * adjust the toggle based on the number of packets
2339: * in this qtd
2340: */
2341: if ((((curlen + mps - 1) / mps) & 1) || curlen == 0)
2342: qtdstatus ^= EHCI_QTD_TOGGLE_MASK;
2343: }
2344: if (len == 0) {
2345: if (! forceshort)
2346: break;
2347: forceshort = 0;
2348: }
2349: DPRINTFN(10,("ehci_alloc_sqtd_chain: extend chain\n"));
2350: dataphys += curlen;
2351: cur = next;
2352: }
2353: cur->qtd.qtd_status |= htole32(EHCI_QTD_IOC);
2354: *ep = cur;
2355:
2356: DPRINTFN(10,("ehci_alloc_sqtd_chain: return sqtd=%p sqtdend=%p\n",
2357: *sp, *ep));
2358:
2359: return (USBD_NORMAL_COMPLETION);
2360:
2361: nomem:
2362: /* XXX free chain */
2363: DPRINTFN(-1,("ehci_alloc_sqtd_chain: no memory\n"));
2364: return (USBD_NOMEM);
2365: }
2366:
2367: void
2368: ehci_free_sqtd_chain(ehci_softc_t *sc, ehci_soft_qtd_t *sqtd,
2369: ehci_soft_qtd_t *sqtdend)
2370: {
2371: ehci_soft_qtd_t *p;
2372: int i;
2373:
2374: DPRINTFN(10,("ehci_free_sqtd_chain: sqtd=%p sqtdend=%p\n",
2375: sqtd, sqtdend));
2376:
2377: for (i = 0; sqtd != sqtdend; sqtd = p, i++) {
2378: p = sqtd->nextqtd;
2379: ehci_free_sqtd(sc, sqtd);
2380: }
2381: }
2382:
2383: /****************/
2384:
2385: /*
2386: * Close a reqular pipe.
2387: * Assumes that there are no pending transactions.
2388: */
2389: void
2390: ehci_close_pipe(usbd_pipe_handle pipe, ehci_soft_qh_t *head)
2391: {
2392: struct ehci_pipe *epipe = (struct ehci_pipe *)pipe;
2393: ehci_softc_t *sc = (ehci_softc_t *)pipe->device->bus;
2394: ehci_soft_qh_t *sqh = epipe->sqh;
2395: int s;
2396:
2397: s = splusb();
2398: ehci_rem_qh(sc, sqh, head);
2399: splx(s);
2400: pipe->endpoint->savedtoggle =
2401: EHCI_QTD_GET_TOGGLE(letoh32(sqh->qh.qh_qtd.qtd_status));
2402: ehci_free_sqh(sc, epipe->sqh);
2403: }
2404:
2405: /*
2406: * Abort a device request.
2407: * If this routine is called at splusb() it guarantees that the request
2408: * will be removed from the hardware scheduling and that the callback
2409: * for it will be called with USBD_CANCELLED status.
2410: * It's impossible to guarantee that the requested transfer will not
2411: * have happened since the hardware runs concurrently.
2412: * If the transaction has already happened we rely on the ordinary
2413: * interrupt processing to process it.
2414: */
2415: void
2416: ehci_abort_xfer(usbd_xfer_handle xfer, usbd_status status)
2417: {
2418: #define exfer EXFER(xfer)
2419: struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
2420: ehci_softc_t *sc = (ehci_softc_t *)epipe->pipe.device->bus;
2421: ehci_soft_qh_t *sqh = epipe->sqh;
2422: ehci_soft_qtd_t *sqtd, *snext, **psqtd;
2423: ehci_physaddr_t cur, us, next;
2424: int s;
2425: int hit;
2426: ehci_soft_qh_t *psqh;
2427:
2428: DPRINTF(("ehci_abort_xfer: xfer=%p pipe=%p\n", xfer, epipe));
2429:
2430: if (sc->sc_dying) {
2431: /* If we're dying, just do the software part. */
2432: s = splusb();
2433: xfer->status = status; /* make software ignore it */
2434: timeout_del(&xfer->timeout_handle);
2435: usb_rem_task(epipe->pipe.device, &exfer->abort_task);
2436: usb_transfer_complete(xfer);
2437: splx(s);
2438: return;
2439: }
2440:
2441: if (xfer->device->bus->intr_context || !curproc)
2442: panic("ehci_abort_xfer: not in process context");
2443:
2444: /*
2445: * If an abort is already in progress then just wait for it to
2446: * complete and return.
2447: */
2448: if (exfer->ehci_xfer_flags & EHCI_XFER_ABORTING) {
2449: DPRINTFN(2, ("ehci_abort_xfer: already aborting\n"));
2450: /* No need to wait if we're aborting from a timeout. */
2451: if (status == USBD_TIMEOUT)
2452: return;
2453: /* Override the status which might be USBD_TIMEOUT. */
2454: xfer->status = status;
2455: DPRINTFN(2, ("ehci_abort_xfer: waiting for abort to finish\n"));
2456: exfer->ehci_xfer_flags |= EHCI_XFER_ABORTWAIT;
2457: while (exfer->ehci_xfer_flags & EHCI_XFER_ABORTING)
2458: tsleep(&exfer->ehci_xfer_flags, PZERO, "ehciaw", 0);
2459: return;
2460: }
2461:
2462: /*
2463: * Step 1: Make interrupt routine and timeouts ignore xfer.
2464: */
2465: s = splusb();
2466: exfer->ehci_xfer_flags |= EHCI_XFER_ABORTING;
2467: xfer->status = status; /* make software ignore it */
2468: timeout_del(&xfer->timeout_handle);
2469: usb_rem_task(epipe->pipe.device, &exfer->abort_task);
2470: splx(s);
2471:
2472: /*
2473: * Step 2: Wait until we know hardware has finished any possible
2474: * use of the xfer. We do this by removing the entire
2475: * queue from the async schedule and waiting for the doorbell.
2476: * Nothing else should be touching the queue now.
2477: */
2478: psqh = sqh->prev;
2479: ehci_rem_qh(sc, sqh, psqh);
2480:
2481: /*
2482: * Step 3: Deactivate all of the qTDs that we will be removing,
2483: * otherwise the queue head may go active again. The EHCI spec
2484: * suggests we should perform the deactivation before removing the
2485: * queue head from the schedule, however the VT6202 (at least) only
2486: * behaves correctly when we deactivate them afterwards.
2487: */
2488: for (sqtd = exfer->sqtdstart; ; sqtd = sqtd->nextqtd) {
2489: sqtd->qtd.qtd_status = htole32(EHCI_QTD_HALTED);
2490: if (sqtd == exfer->sqtdend)
2491: break;
2492: }
2493: ehci_sync_hc(sc);
2494:
2495: /*
2496: * Step 4: make sure the soft interrupt routine
2497: * has run. This should remove any completed items off the queue.
2498: * The hardware has no reference to completed items (TDs).
2499: * It's safe to remove them at any time.
2500: * use of the xfer. Also make sure the soft interrupt routine
2501: * has run.
2502: */
2503: s = splusb();
2504: #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
2505: sc->sc_softwake = 1;
2506: #endif /* __HAVE_GENERIC_SOFT_INTERRUPTS */
2507: usb_schedsoftintr(&sc->sc_bus);
2508: #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
2509: tsleep(&sc->sc_softwake, PZERO, "ehciab", 0);
2510: #endif /* __HAVE_GENERIC_SOFT_INTERRUPTS */
2511:
2512: /*
2513: * Step 5: Remove any vestiges of the xfer from the hardware.
2514: * The complication here is that the hardware may have executed
2515: * into or even beyond the xfer we're trying to abort.
2516: * So as we're scanning the TDs of this xfer we check if
2517: * the hardware points to any of them.
2518: *
2519: * first we need to see if there are any transfers
2520: * on this queue before the xfer we are aborting.. we need
2521: * to update any pointers that point to us to point past
2522: * the aborting xfer. (If there is something past us).
2523: * Hardware and software.
2524: */
2525: cur = EHCI_LINK_ADDR(letoh32(sqh->qh.qh_curqtd));
2526: hit = 0;
2527:
2528: /* If they initially point here. */
2529: us = exfer->sqtdstart->physaddr;
2530:
2531: /* We will change them to point here */
2532: snext = exfer->sqtdend->nextqtd;
2533: next = snext ? snext->physaddr : EHCI_NULL;
2534:
2535: /*
2536: * Now loop through any qTDs before us and keep track of the pointer
2537: * that points to us for the end.
2538: */
2539: psqtd = &sqh->sqtd;
2540: sqtd = sqh->sqtd;
2541: while (sqtd && sqtd != exfer->sqtdstart) {
2542: hit |= (cur == sqtd->physaddr);
2543: if (EHCI_LINK_ADDR(letoh32(sqtd->qtd.qtd_next)) == us)
2544: sqtd->qtd.qtd_next = next;
2545: if (EHCI_LINK_ADDR(letoh32(sqtd->qtd.qtd_altnext)) == us)
2546: sqtd->qtd.qtd_altnext = next;
2547: psqtd = &sqtd->nextqtd;
2548: sqtd = sqtd->nextqtd;
2549: }
2550: /* make the software pointer bypass us too */
2551: *psqtd = exfer->sqtdend->nextqtd;
2552:
2553: /*
2554: * If we already saw the active one then we are pretty much done.
2555: * We've done all the relinking we need to do.
2556: */
2557: if (!hit) {
2558:
2559: /*
2560: * Now reinitialise the QH to point to the next qTD
2561: * (if there is one). We only need to do this if
2562: * it was previously pointing to us.
2563: * XXX Not quite sure what to do about the data toggle.
2564: */
2565: sqtd = exfer->sqtdstart;
2566: for (sqtd = exfer->sqtdstart; ; sqtd = sqtd->nextqtd) {
2567: if (cur == sqtd->physaddr) {
2568: hit++;
2569: }
2570: if (sqtd == exfer->sqtdend)
2571: break;
2572: }
2573: sqtd = sqtd->nextqtd;
2574: /*
2575: * Only need to alter the QH if it was pointing at a qTD
2576: * that we are removing.
2577: */
2578: if (hit) {
2579: if (snext) {
2580: ehci_set_qh_qtd(sqh, snext);
2581: } else {
2582:
2583: sqh->qh.qh_curqtd = 0; /* unlink qTDs */
2584: sqh->qh.qh_qtd.qtd_status = 0;
2585: sqh->qh.qh_qtd.qtd_next =
2586: sqh->qh.qh_qtd.qtd_altnext = EHCI_NULL;
2587: DPRINTFN(1,("ehci_abort_xfer: no hit\n"));
2588: }
2589: }
2590: }
2591: ehci_add_qh(sqh, psqh);
2592:
2593: /*
2594: * Step 6: Execute callback.
2595: */
2596: #ifdef DIAGNOSTIC
2597: exfer->isdone = 1;
2598: #endif
2599: /* Do the wakeup first to avoid touching the xfer after the callback. */
2600: exfer->ehci_xfer_flags &= ~EHCI_XFER_ABORTING;
2601: if (exfer->ehci_xfer_flags & EHCI_XFER_ABORTWAIT) {
2602: exfer->ehci_xfer_flags &= ~EHCI_XFER_ABORTWAIT;
2603: wakeup(&exfer->ehci_xfer_flags);
2604: }
2605: usb_transfer_complete(xfer);
2606:
2607: splx(s);
2608: #undef exfer
2609: }
2610:
2611: void
2612: ehci_timeout(void *addr)
2613: {
2614: struct ehci_xfer *exfer = addr;
2615: struct ehci_pipe *epipe = (struct ehci_pipe *)exfer->xfer.pipe;
2616: ehci_softc_t *sc = (ehci_softc_t *)epipe->pipe.device->bus;
2617:
2618: DPRINTF(("ehci_timeout: exfer=%p\n", exfer));
2619: #ifdef USB_DEBUG
2620: if (ehcidebug > 1)
2621: usbd_dump_pipe(exfer->xfer.pipe);
2622: #endif
2623:
2624: if (sc->sc_dying) {
2625: ehci_abort_xfer(&exfer->xfer, USBD_TIMEOUT);
2626: return;
2627: }
2628:
2629: /* Execute the abort in a process context. */
2630: usb_add_task(exfer->xfer.pipe->device, &exfer->abort_task);
2631: }
2632:
2633: void
2634: ehci_timeout_task(void *addr)
2635: {
2636: usbd_xfer_handle xfer = addr;
2637: int s;
2638:
2639: DPRINTF(("ehci_timeout_task: xfer=%p\n", xfer));
2640:
2641: s = splusb();
2642: ehci_abort_xfer(xfer, USBD_TIMEOUT);
2643: splx(s);
2644: }
2645:
2646: /*
2647: * Some EHCI chips from VIA seem to trigger interrupts before writing back the
2648: * qTD status, or miss signalling occasionally under heavy load. If the host
2649: * machine is too fast, we we can miss transaction completion - when we scan
2650: * the active list the transaction still seems to be active. This generally
2651: * exhibits itself as a umass stall that never recovers.
2652: *
2653: * We work around this behaviour by setting up this callback after any softintr
2654: * that completes with transactions still pending, giving us another chance to
2655: * check for completion after the writeback has taken place.
2656: */
2657: void
2658: ehci_intrlist_timeout(void *arg)
2659: {
2660: ehci_softc_t *sc = arg;
2661: int s = splusb();
2662:
2663: DPRINTFN(1, ("ehci_intrlist_timeout\n"));
2664: usb_schedsoftintr(&sc->sc_bus);
2665:
2666: splx(s);
2667: }
2668:
2669: /************************/
2670:
2671: usbd_status
2672: ehci_device_ctrl_transfer(usbd_xfer_handle xfer)
2673: {
2674: usbd_status err;
2675:
2676: /* Insert last in queue. */
2677: err = usb_insert_transfer(xfer);
2678: if (err)
2679: return (err);
2680:
2681: /* Pipe isn't running, start first */
2682: return (ehci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
2683: }
2684:
2685: usbd_status
2686: ehci_device_ctrl_start(usbd_xfer_handle xfer)
2687: {
2688: ehci_softc_t *sc = (ehci_softc_t *)xfer->pipe->device->bus;
2689: usbd_status err;
2690:
2691: if (sc->sc_dying)
2692: return (USBD_IOERROR);
2693:
2694: #ifdef DIAGNOSTIC
2695: if (!(xfer->rqflags & URQ_REQUEST)) {
2696: /* XXX panic */
2697: printf("ehci_device_ctrl_transfer: not a request\n");
2698: return (USBD_INVAL);
2699: }
2700: #endif
2701:
2702: err = ehci_device_request(xfer);
2703: if (err)
2704: return (err);
2705:
2706: if (sc->sc_bus.use_polling)
2707: ehci_waitintr(sc, xfer);
2708: return (USBD_IN_PROGRESS);
2709: }
2710:
2711: void
2712: ehci_device_ctrl_done(usbd_xfer_handle xfer)
2713: {
2714: struct ehci_xfer *ex = EXFER(xfer);
2715: ehci_softc_t *sc = (ehci_softc_t *)xfer->pipe->device->bus;
2716: /*struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;*/
2717:
2718: DPRINTFN(10,("ehci_ctrl_done: xfer=%p\n", xfer));
2719:
2720: #ifdef DIAGNOSTIC
2721: if (!(xfer->rqflags & URQ_REQUEST)) {
2722: panic("ehci_ctrl_done: not a request");
2723: }
2724: #endif
2725:
2726: if (xfer->status != USBD_NOMEM && ehci_active_intr_list(ex)) {
2727: ehci_del_intr_list(ex); /* remove from active list */
2728: ehci_free_sqtd_chain(sc, ex->sqtdstart, NULL);
2729: }
2730:
2731: DPRINTFN(5, ("ehci_ctrl_done: length=%d\n", xfer->actlen));
2732: }
2733:
2734: /* Abort a device control request. */
2735: void
2736: ehci_device_ctrl_abort(usbd_xfer_handle xfer)
2737: {
2738: DPRINTF(("ehci_device_ctrl_abort: xfer=%p\n", xfer));
2739: ehci_abort_xfer(xfer, USBD_CANCELLED);
2740: }
2741:
2742: /* Close a device control pipe. */
2743: void
2744: ehci_device_ctrl_close(usbd_pipe_handle pipe)
2745: {
2746: ehci_softc_t *sc = (ehci_softc_t *)pipe->device->bus;
2747: /*struct ehci_pipe *epipe = (struct ehci_pipe *)pipe;*/
2748:
2749: DPRINTF(("ehci_device_ctrl_close: pipe=%p\n", pipe));
2750: ehci_close_pipe(pipe, sc->sc_async_head);
2751: }
2752:
2753: usbd_status
2754: ehci_device_request(usbd_xfer_handle xfer)
2755: {
2756: #define exfer EXFER(xfer)
2757: struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
2758: usb_device_request_t *req = &xfer->request;
2759: usbd_device_handle dev = epipe->pipe.device;
2760: ehci_softc_t *sc = (ehci_softc_t *)dev->bus;
2761: int addr = dev->address;
2762: ehci_soft_qtd_t *setup, *stat, *next;
2763: ehci_soft_qh_t *sqh;
2764: int isread;
2765: int len;
2766: usbd_status err;
2767: int s;
2768:
2769: isread = req->bmRequestType & UT_READ;
2770: len = UGETW(req->wLength);
2771:
2772: DPRINTFN(3,("ehci_device_request: type=0x%02x, request=0x%02x, "
2773: "wValue=0x%04x, wIndex=0x%04x len=%d, addr=%d, endpt=%d\n",
2774: req->bmRequestType, req->bRequest, UGETW(req->wValue),
2775: UGETW(req->wIndex), len, addr,
2776: epipe->pipe.endpoint->edesc->bEndpointAddress));
2777:
2778: setup = ehci_alloc_sqtd(sc);
2779: if (setup == NULL) {
2780: err = USBD_NOMEM;
2781: goto bad1;
2782: }
2783: stat = ehci_alloc_sqtd(sc);
2784: if (stat == NULL) {
2785: err = USBD_NOMEM;
2786: goto bad2;
2787: }
2788:
2789: sqh = epipe->sqh;
2790: epipe->u.ctl.length = len;
2791:
2792: /* Update device address and length since they may have changed
2793: during the setup of the control pipe in usbd_new_device(). */
2794: /* XXX This only needs to be done once, but it's too early in open. */
2795: /* XXXX Should not touch ED here! */
2796: sqh->qh.qh_endp =
2797: (sqh->qh.qh_endp & htole32(~(EHCI_QH_ADDRMASK | EHCI_QH_MPLMASK))) |
2798: htole32(
2799: EHCI_QH_SET_ADDR(addr) |
2800: EHCI_QH_SET_MPL(UGETW(epipe->pipe.endpoint->edesc->wMaxPacketSize))
2801: );
2802:
2803: /* Set up data transaction */
2804: if (len != 0) {
2805: ehci_soft_qtd_t *end;
2806:
2807: err = ehci_alloc_sqtd_chain(epipe, sc, len, isread, xfer,
2808: &next, &end);
2809: if (err)
2810: goto bad3;
2811: end->qtd.qtd_status &= htole32(~EHCI_QTD_IOC);
2812: end->nextqtd = stat;
2813: end->qtd.qtd_next =
2814: end->qtd.qtd_altnext = htole32(stat->physaddr);
2815: } else {
2816: next = stat;
2817: }
2818:
2819: memcpy(KERNADDR(&epipe->u.ctl.reqdma, 0), req, sizeof(*req));
2820:
2821: /* Clear toggle */
2822: setup->qtd.qtd_status = htole32(
2823: EHCI_QTD_ACTIVE |
2824: EHCI_QTD_SET_PID(EHCI_QTD_PID_SETUP) |
2825: EHCI_QTD_SET_CERR(3) |
2826: EHCI_QTD_SET_TOGGLE(0) |
2827: EHCI_QTD_SET_BYTES(sizeof(*req)));
2828: setup->qtd.qtd_buffer[0] = htole32(DMAADDR(&epipe->u.ctl.reqdma, 0));
2829: setup->qtd.qtd_buffer_hi[0] = 0;
2830: setup->nextqtd = next;
2831: setup->qtd.qtd_next = setup->qtd.qtd_altnext = htole32(next->physaddr);
2832: setup->xfer = xfer;
2833: setup->len = sizeof(*req);
2834:
2835: stat->qtd.qtd_status = htole32(
2836: EHCI_QTD_ACTIVE |
2837: EHCI_QTD_SET_PID(isread ? EHCI_QTD_PID_OUT : EHCI_QTD_PID_IN) |
2838: EHCI_QTD_SET_CERR(3) |
2839: EHCI_QTD_SET_TOGGLE(1) |
2840: EHCI_QTD_IOC);
2841: stat->qtd.qtd_buffer[0] = 0; /* XXX not needed? */
2842: stat->qtd.qtd_buffer_hi[0] = 0; /* XXX not needed? */
2843: stat->nextqtd = NULL;
2844: stat->qtd.qtd_next = stat->qtd.qtd_altnext = EHCI_NULL;
2845: stat->xfer = xfer;
2846: stat->len = 0;
2847:
2848: #ifdef EHCI_DEBUG
2849: if (ehcidebug > 5) {
2850: DPRINTF(("ehci_device_request:\n"));
2851: ehci_dump_sqh(sqh);
2852: ehci_dump_sqtds(setup);
2853: }
2854: #endif
2855:
2856: exfer->sqtdstart = setup;
2857: exfer->sqtdend = stat;
2858: #ifdef DIAGNOSTIC
2859: if (!exfer->isdone) {
2860: printf("ehci_device_request: not done, exfer=%p\n", exfer);
2861: }
2862: exfer->isdone = 0;
2863: #endif
2864:
2865: /* Insert qTD in QH list. */
2866: s = splusb();
2867: ehci_set_qh_qtd(sqh, setup);
2868: if (xfer->timeout && !sc->sc_bus.use_polling) {
2869: timeout_del(&xfer->timeout_handle);
2870: timeout_set(&xfer->timeout_handle, ehci_timeout, xfer);
2871: timeout_add(&xfer->timeout_handle, mstohz(xfer->timeout));
2872: }
2873: ehci_add_intr_list(sc, exfer);
2874: xfer->status = USBD_IN_PROGRESS;
2875: splx(s);
2876:
2877: #ifdef EHCI_DEBUG
2878: if (ehcidebug > 10) {
2879: DPRINTF(("ehci_device_request: status=%x\n",
2880: EOREAD4(sc, EHCI_USBSTS)));
2881: delay(10000);
2882: ehci_dump_regs(sc);
2883: ehci_dump_sqh(sc->sc_async_head);
2884: ehci_dump_sqh(sqh);
2885: ehci_dump_sqtds(setup);
2886: }
2887: #endif
2888:
2889: return (USBD_NORMAL_COMPLETION);
2890:
2891: bad3:
2892: ehci_free_sqtd(sc, stat);
2893: bad2:
2894: ehci_free_sqtd(sc, setup);
2895: bad1:
2896: DPRINTFN(-1,("ehci_device_request: no memory\n"));
2897: xfer->status = err;
2898: usb_transfer_complete(xfer);
2899: return (err);
2900: #undef exfer
2901: }
2902:
2903: /************************/
2904:
2905: usbd_status
2906: ehci_device_bulk_transfer(usbd_xfer_handle xfer)
2907: {
2908: usbd_status err;
2909:
2910: /* Insert last in queue. */
2911: err = usb_insert_transfer(xfer);
2912: if (err)
2913: return (err);
2914:
2915: /* Pipe isn't running, start first */
2916: return (ehci_device_bulk_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
2917: }
2918:
2919: usbd_status
2920: ehci_device_bulk_start(usbd_xfer_handle xfer)
2921: {
2922: #define exfer EXFER(xfer)
2923: struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
2924: usbd_device_handle dev = epipe->pipe.device;
2925: ehci_softc_t *sc = (ehci_softc_t *)dev->bus;
2926: ehci_soft_qtd_t *data, *dataend;
2927: ehci_soft_qh_t *sqh;
2928: usbd_status err;
2929: int len, isread, endpt;
2930: int s;
2931:
2932: DPRINTFN(2, ("ehci_device_bulk_start: xfer=%p len=%d flags=%d\n",
2933: xfer, xfer->length, xfer->flags));
2934:
2935: if (sc->sc_dying)
2936: return (USBD_IOERROR);
2937:
2938: #ifdef DIAGNOSTIC
2939: if (xfer->rqflags & URQ_REQUEST)
2940: panic("ehci_device_bulk_start: a request");
2941: #endif
2942:
2943: len = xfer->length;
2944: endpt = epipe->pipe.endpoint->edesc->bEndpointAddress;
2945: isread = UE_GET_DIR(endpt) == UE_DIR_IN;
2946: sqh = epipe->sqh;
2947:
2948: epipe->u.bulk.length = len;
2949:
2950: err = ehci_alloc_sqtd_chain(epipe, sc, len, isread, xfer, &data,
2951: &dataend);
2952: if (err) {
2953: DPRINTFN(-1,("ehci_device_bulk_start: no memory\n"));
2954: xfer->status = err;
2955: usb_transfer_complete(xfer);
2956: return (err);
2957: }
2958:
2959: #ifdef EHCI_DEBUG
2960: if (ehcidebug > 5) {
2961: DPRINTF(("ehci_device_bulk_start: data(1)\n"));
2962: ehci_dump_sqh(sqh);
2963: ehci_dump_sqtds(data);
2964: }
2965: #endif
2966:
2967: /* Set up interrupt info. */
2968: exfer->sqtdstart = data;
2969: exfer->sqtdend = dataend;
2970: #ifdef DIAGNOSTIC
2971: if (!exfer->isdone) {
2972: printf("ehci_device_bulk_start: not done, ex=%p\n", exfer);
2973: }
2974: exfer->isdone = 0;
2975: #endif
2976:
2977: s = splusb();
2978: ehci_set_qh_qtd(sqh, data);
2979: if (xfer->timeout && !sc->sc_bus.use_polling) {
2980: timeout_del(&xfer->timeout_handle);
2981: timeout_set(&xfer->timeout_handle, ehci_timeout, xfer);
2982: timeout_add(&xfer->timeout_handle, mstohz(xfer->timeout));
2983: }
2984: ehci_add_intr_list(sc, exfer);
2985: xfer->status = USBD_IN_PROGRESS;
2986: splx(s);
2987:
2988: #ifdef EHCI_DEBUG
2989: if (ehcidebug > 10) {
2990: DPRINTF(("ehci_device_bulk_start: data(2)\n"));
2991: delay(10000);
2992: DPRINTF(("ehci_device_bulk_start: data(3)\n"));
2993: ehci_dump_regs(sc);
2994: #if 0
2995: printf("async_head:\n");
2996: ehci_dump_sqh(sc->sc_async_head);
2997: #endif
2998: printf("sqh:\n");
2999: ehci_dump_sqh(sqh);
3000: ehci_dump_sqtds(data);
3001: }
3002: #endif
3003:
3004: if (sc->sc_bus.use_polling)
3005: ehci_waitintr(sc, xfer);
3006:
3007: return (USBD_IN_PROGRESS);
3008: #undef exfer
3009: }
3010:
3011: void
3012: ehci_device_bulk_abort(usbd_xfer_handle xfer)
3013: {
3014: DPRINTF(("ehci_device_bulk_abort: xfer=%p\n", xfer));
3015: ehci_abort_xfer(xfer, USBD_CANCELLED);
3016: }
3017:
3018: /*
3019: * Close a device bulk pipe.
3020: */
3021: void
3022: ehci_device_bulk_close(usbd_pipe_handle pipe)
3023: {
3024: ehci_softc_t *sc = (ehci_softc_t *)pipe->device->bus;
3025:
3026: DPRINTF(("ehci_device_bulk_close: pipe=%p\n", pipe));
3027: ehci_close_pipe(pipe, sc->sc_async_head);
3028: }
3029:
3030: void
3031: ehci_device_bulk_done(usbd_xfer_handle xfer)
3032: {
3033: struct ehci_xfer *ex = EXFER(xfer);
3034: ehci_softc_t *sc = (ehci_softc_t *)xfer->pipe->device->bus;
3035: /*struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;*/
3036:
3037: DPRINTFN(10,("ehci_bulk_done: xfer=%p, actlen=%d\n",
3038: xfer, xfer->actlen));
3039:
3040: if (xfer->status != USBD_NOMEM && ehci_active_intr_list(ex)) {
3041: ehci_del_intr_list(ex); /* remove from active list */
3042: ehci_free_sqtd_chain(sc, ex->sqtdstart, NULL);
3043: }
3044:
3045: DPRINTFN(5, ("ehci_bulk_done: length=%d\n", xfer->actlen));
3046: }
3047:
3048: /************************/
3049:
3050: usbd_status
3051: ehci_device_setintr(ehci_softc_t *sc, ehci_soft_qh_t *sqh, int ival)
3052: {
3053: struct ehci_soft_islot *isp;
3054: int islot, lev;
3055:
3056: /* Find a poll rate that is large enough. */
3057: for (lev = EHCI_IPOLLRATES - 1; lev > 0; lev--)
3058: if (EHCI_ILEV_IVAL(lev) <= ival)
3059: break;
3060:
3061: /* Pick an interrupt slot at the right level. */
3062: /* XXX could do better than picking at random */
3063: if (cold) {
3064: /* XXX prevent panics at boot by not using arc4random */
3065: sc->sc_rand = (sc->sc_rand + 192) % sc->sc_flsize;
3066: islot = EHCI_IQHIDX(lev, sc->sc_rand);
3067: } else
3068: islot = EHCI_IQHIDX(lev, arc4random());
3069:
3070: sqh->islot = islot;
3071: isp = &sc->sc_islots[islot];
3072: ehci_add_qh(sqh, isp->sqh);
3073:
3074: return (USBD_NORMAL_COMPLETION);
3075: }
3076:
3077: usbd_status
3078: ehci_device_intr_transfer(usbd_xfer_handle xfer)
3079: {
3080: usbd_status err;
3081:
3082: /* Insert last in queue. */
3083: err = usb_insert_transfer(xfer);
3084: if (err)
3085: return (err);
3086:
3087: /*
3088: * Pipe isn't running (otherwise err would be USBD_INPROG),
3089: * so start it first.
3090: */
3091: return (ehci_device_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
3092: }
3093:
3094: usbd_status
3095: ehci_device_intr_start(usbd_xfer_handle xfer)
3096: {
3097: #define exfer EXFER(xfer)
3098: struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
3099: usbd_device_handle dev = xfer->pipe->device;
3100: ehci_softc_t *sc = (ehci_softc_t *)dev->bus;
3101: ehci_soft_qtd_t *data, *dataend;
3102: ehci_soft_qh_t *sqh;
3103: usbd_status err;
3104: int len, isread, endpt;
3105: int s;
3106:
3107: DPRINTFN(2, ("ehci_device_intr_start: xfer=%p len=%d flags=%d\n",
3108: xfer, xfer->length, xfer->flags));
3109:
3110: if (sc->sc_dying)
3111: return (USBD_IOERROR);
3112:
3113: #ifdef DIAGNOSTIC
3114: if (xfer->rqflags & URQ_REQUEST)
3115: panic("ehci_device_intr_start: a request");
3116: #endif
3117:
3118: len = xfer->length;
3119: endpt = epipe->pipe.endpoint->edesc->bEndpointAddress;
3120: isread = UE_GET_DIR(endpt) == UE_DIR_IN;
3121: sqh = epipe->sqh;
3122:
3123: epipe->u.intr.length = len;
3124:
3125: err = ehci_alloc_sqtd_chain(epipe, sc, len, isread, xfer, &data,
3126: &dataend);
3127: if (err) {
3128: DPRINTFN(-1, ("ehci_device_intr_start: no memory\n"));
3129: xfer->status = err;
3130: usb_transfer_complete(xfer);
3131: return (err);
3132: }
3133:
3134: #ifdef EHCI_DEBUG
3135: if (ehcidebug > 5) {
3136: DPRINTF(("ehci_device_intr_start: data(1)\n"));
3137: ehci_dump_sqh(sqh);
3138: ehci_dump_sqtds(data);
3139: }
3140: #endif
3141:
3142: /* Set up interrupt info. */
3143: exfer->sqtdstart = data;
3144: exfer->sqtdend = dataend;
3145: #ifdef DIAGNOSTIC
3146: if (!exfer->isdone)
3147: printf("ehci_device_intr_start: not done, ex=%p\n", exfer);
3148: exfer->isdone = 0;
3149: #endif
3150:
3151: s = splusb();
3152: ehci_set_qh_qtd(sqh, data);
3153: if (xfer->timeout && !sc->sc_bus.use_polling) {
3154: timeout_del(&xfer->timeout_handle);
3155: timeout_set(&xfer->timeout_handle, ehci_timeout, xfer);
3156: timeout_add(&xfer->timeout_handle, mstohz(xfer->timeout));
3157: }
3158: ehci_add_intr_list(sc, exfer);
3159: xfer->status = USBD_IN_PROGRESS;
3160: splx(s);
3161:
3162: #ifdef EHCI_DEBUG
3163: if (ehcidebug > 10) {
3164: DPRINTF(("ehci_device_intr_start: data(2)\n"));
3165: delay(10000);
3166: DPRINTF(("ehci_device_intr_start: data(3)\n"));
3167: ehci_dump_regs(sc);
3168: printf("sqh:\n");
3169: ehci_dump_sqh(sqh);
3170: ehci_dump_sqtds(data);
3171: }
3172: #endif
3173:
3174: if (sc->sc_bus.use_polling)
3175: ehci_waitintr(sc, xfer);
3176:
3177: return (USBD_IN_PROGRESS);
3178: #undef exfer
3179: }
3180:
3181: void
3182: ehci_device_intr_abort(usbd_xfer_handle xfer)
3183: {
3184: DPRINTFN(1, ("ehci_device_intr_abort: xfer=%p\n", xfer));
3185: if (xfer->pipe->intrxfer == xfer) {
3186: DPRINTFN(1, ("ehci_device_intr_abort: remove\n"));
3187: xfer->pipe->intrxfer = NULL;
3188: }
3189: ehci_abort_xfer(xfer, USBD_CANCELLED);
3190: }
3191:
3192: void
3193: ehci_device_intr_close(usbd_pipe_handle pipe)
3194: {
3195: ehci_softc_t *sc = (ehci_softc_t *)pipe->device->bus;
3196: struct ehci_pipe *epipe = (struct ehci_pipe *)pipe;
3197: struct ehci_soft_islot *isp;
3198:
3199: isp = &sc->sc_islots[epipe->sqh->islot];
3200: ehci_close_pipe(pipe, isp->sqh);
3201: }
3202:
3203: void
3204: ehci_device_intr_done(usbd_xfer_handle xfer)
3205: {
3206: #define exfer EXFER(xfer)
3207: struct ehci_xfer *ex = EXFER(xfer);
3208: ehci_softc_t *sc = (ehci_softc_t *)xfer->pipe->device->bus;
3209: struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe;
3210: ehci_soft_qtd_t *data, *dataend;
3211: ehci_soft_qh_t *sqh;
3212: usbd_status err;
3213: int len, isread, endpt, s;
3214:
3215: DPRINTFN(10, ("ehci_device_intr_done: xfer=%p, actlen=%d\n",
3216: xfer, xfer->actlen));
3217:
3218: if (xfer->pipe->repeat) {
3219: ehci_free_sqtd_chain(sc, ex->sqtdstart, NULL);
3220:
3221: len = epipe->u.intr.length;
3222: xfer->length = len;
3223: endpt = epipe->pipe.endpoint->edesc->bEndpointAddress;
3224: isread = UE_GET_DIR(endpt) == UE_DIR_IN;
3225: sqh = epipe->sqh;
3226:
3227: err = ehci_alloc_sqtd_chain(epipe, sc, len, isread, xfer,
3228: &data, &dataend);
3229: if (err) {
3230: DPRINTFN(-1, ("ehci_device_intr_done: no memory\n"));
3231: xfer->status = err;
3232: return;
3233: }
3234:
3235: /* Set up interrupt info. */
3236: exfer->sqtdstart = data;
3237: exfer->sqtdend = dataend;
3238: #ifdef DIAGNOSTIC
3239: if (!exfer->isdone) {
3240: printf("ehci_device_intr_done: not done, ex=%p\n",
3241: exfer);
3242: }
3243: exfer->isdone = 0;
3244: #endif
3245:
3246: s = splusb();
3247: ehci_set_qh_qtd(sqh, data);
3248: if (xfer->timeout && !sc->sc_bus.use_polling) {
3249: timeout_del(&xfer->timeout_handle);
3250: timeout_set(&xfer->timeout_handle, ehci_timeout, xfer);
3251: timeout_add(&xfer->timeout_handle,
3252: mstohz(xfer->timeout));
3253: }
3254: splx(s);
3255:
3256: xfer->status = USBD_IN_PROGRESS;
3257: } else if (xfer->status != USBD_NOMEM && ehci_active_intr_list(ex)) {
3258: ehci_del_intr_list(ex); /* remove from active list */
3259: ehci_free_sqtd_chain(sc, ex->sqtdstart, NULL);
3260: }
3261: #undef exfer
3262: }
3263:
3264: /************************/
3265:
3266: usbd_status ehci_device_isoc_transfer(usbd_xfer_handle xfer) { return USBD_IOERROR; }
3267: usbd_status ehci_device_isoc_start(usbd_xfer_handle xfer) { return USBD_IOERROR; }
3268: void ehci_device_isoc_abort(usbd_xfer_handle xfer) { }
3269: void ehci_device_isoc_close(usbd_pipe_handle pipe) { }
3270: void ehci_device_isoc_done(usbd_xfer_handle xfer) { }
CVSweb