1 /* $OpenBSD: ehcivar.h,v 1.28 2013/11/07 10:15:15 mpi Exp $ */ 2 /* $NetBSD: ehcivar.h,v 1.19 2005/04/29 15:04:29 augustss Exp $ */ 3 4 /* 5 * Copyright (c) 2001 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). 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 * 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 struct ehci_soft_qtd { 34 struct ehci_qtd qtd; 35 struct ehci_soft_qtd *nextqtd; /* mirrors nextqtd in TD */ 36 ehci_physaddr_t physaddr; 37 struct usb_dma dma; /* qTD's DMA infos */ 38 int offs; /* qTD's offset in struct usb_dma */ 39 LIST_ENTRY(ehci_soft_qtd) hnext; 40 u_int16_t len; 41 }; 42 #define EHCI_SQTD_SIZE ((sizeof (struct ehci_soft_qtd) + EHCI_QTD_ALIGN - 1) / EHCI_QTD_ALIGN * EHCI_QTD_ALIGN) 43 #define EHCI_SQTD_CHUNK (EHCI_PAGE_SIZE / EHCI_SQTD_SIZE) 44 45 struct ehci_soft_qh { 46 struct ehci_qh qh; 47 struct ehci_soft_qh *next; 48 struct ehci_soft_qh *prev; 49 struct ehci_soft_qtd *sqtd; 50 ehci_physaddr_t physaddr; 51 struct usb_dma dma; /* QH's DMA infos */ 52 int offs; /* QH's offset in struct usb_dma */ 53 int islot; 54 }; 55 #define EHCI_SQH_SIZE ((sizeof (struct ehci_soft_qh) + EHCI_QH_ALIGN - 1) / EHCI_QH_ALIGN * EHCI_QH_ALIGN) 56 #define EHCI_SQH_CHUNK (EHCI_PAGE_SIZE / EHCI_SQH_SIZE) 57 58 struct ehci_soft_itd { 59 struct ehci_itd itd; 60 union { 61 struct { 62 /* soft_itds links in a periodic frame*/ 63 struct ehci_soft_itd *next; 64 struct ehci_soft_itd *prev; 65 } frame_list; 66 /* circular list of free itds */ 67 LIST_ENTRY(ehci_soft_itd) free_list; 68 } u; 69 struct ehci_soft_itd *xfer_next; /* Next soft_itd in xfer */ 70 ehci_physaddr_t physaddr; 71 struct usb_dma dma; 72 int offs; 73 int slot; 74 struct timeval t; /* store free time */ 75 }; 76 #define EHCI_ITD_SIZE ((sizeof(struct ehci_soft_itd) + EHCI_QH_ALIGN - 1) / EHCI_ITD_ALIGN * EHCI_ITD_ALIGN) 77 #define EHCI_ITD_CHUNK (EHCI_PAGE_SIZE / EHCI_ITD_SIZE) 78 79 struct ehci_xfer { 80 struct usbd_xfer xfer; 81 TAILQ_ENTRY(ehci_xfer) inext; /* list of active xfers */ 82 struct ehci_soft_qtd *sqtdstart; 83 struct ehci_soft_qtd *sqtdend; 84 struct ehci_soft_itd *itdstart; 85 struct ehci_soft_itd *itdend; 86 u_int32_t ehci_xfer_flags; 87 #ifdef DIAGNOSTIC 88 int isdone; 89 #endif 90 }; 91 #define EHCI_XFER_ABORTING 0x0001 /* xfer is aborting. */ 92 #define EHCI_XFER_ABORTWAIT 0x0002 /* abort completion is being awaited. */ 93 94 #define EXFER(xfer) ((struct ehci_xfer *)(xfer)) 95 96 /* Information about an entry in the interrupt list. */ 97 struct ehci_soft_islot { 98 struct ehci_soft_qh *sqh; /* Queue Head. */ 99 }; 100 101 #define EHCI_FRAMELIST_MAXCOUNT 1024 102 #define EHCI_IPOLLRATES 8 /* Poll rates (1ms, 2, 4, 8 .. 128) */ 103 #define EHCI_INTRQHS ((1 << EHCI_IPOLLRATES) - 1) 104 #define EHCI_IQHIDX(lev, pos) \ 105 ((((pos) & ((1 << (lev)) - 1)) | (1 << (lev))) - 1) 106 #define EHCI_ILEV_IVAL(lev) (1 << (lev)) 107 108 109 #define EHCI_HASH_SIZE 128 110 #define EHCI_COMPANION_MAX 8 111 112 #define EHCI_FREE_LIST_INTERVAL 100 113 114 struct ehci_softc { 115 struct usbd_bus sc_bus; /* base device */ 116 bus_space_tag_t iot; 117 bus_space_handle_t ioh; 118 bus_size_t sc_size; 119 u_int sc_offs; /* offset to operational regs */ 120 int sc_flags; /* misc flags */ 121 #define EHCIF_DROPPED_INTR_WORKAROUND 0x01 122 123 char sc_vendor[16]; /* vendor string for root hub */ 124 int sc_id_vendor; /* vendor ID for root hub */ 125 126 struct usb_dma sc_fldma; 127 ehci_link_t *sc_flist; 128 u_int sc_flsize; 129 130 struct ehci_soft_islot sc_islots[EHCI_INTRQHS]; 131 132 /* jcmm - an array matching sc_flist, but with software pointers, 133 * not hardware address pointers 134 */ 135 struct ehci_soft_itd **sc_softitds; 136 137 TAILQ_HEAD(, ehci_xfer) sc_intrhead; 138 139 struct ehci_soft_qh *sc_freeqhs; 140 struct ehci_soft_qtd *sc_freeqtds; 141 LIST_HEAD(sc_freeitds, ehci_soft_itd) sc_freeitds; 142 143 int sc_noport; 144 u_int8_t sc_addr; /* device address */ 145 u_int8_t sc_conf; /* device configuration */ 146 struct usbd_xfer *sc_intrxfer; 147 char sc_isreset; 148 char sc_softwake; 149 150 u_int32_t sc_eintrs; 151 struct ehci_soft_qh *sc_async_head; 152 153 SIMPLEQ_HEAD(, usbd_xfer) sc_free_xfers; /* free xfers */ 154 155 struct rwlock sc_doorbell_lock; 156 157 struct timeout sc_tmo_intrlist; 158 159 struct device *sc_child; /* /dev/usb# device */ 160 }; 161 162 #define EREAD1(sc, a) bus_space_read_1((sc)->iot, (sc)->ioh, (a)) 163 #define EREAD2(sc, a) bus_space_read_2((sc)->iot, (sc)->ioh, (a)) 164 #define EREAD4(sc, a) bus_space_read_4((sc)->iot, (sc)->ioh, (a)) 165 #define EWRITE1(sc, a, x) bus_space_write_1((sc)->iot, (sc)->ioh, (a), (x)) 166 #define EWRITE2(sc, a, x) bus_space_write_2((sc)->iot, (sc)->ioh, (a), (x)) 167 #define EWRITE4(sc, a, x) bus_space_write_4((sc)->iot, (sc)->ioh, (a), (x)) 168 #define EOREAD1(sc, a) bus_space_read_1((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a)) 169 #define EOREAD2(sc, a) bus_space_read_2((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a)) 170 #define EOREAD4(sc, a) bus_space_read_4((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a)) 171 #define EOWRITE1(sc, a, x) bus_space_write_1((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a), (x)) 172 #define EOWRITE2(sc, a, x) bus_space_write_2((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a), (x)) 173 #define EOWRITE4(sc, a, x) bus_space_write_4((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a), (x)) 174 175 usbd_status ehci_init(struct ehci_softc *); 176 int ehci_intr(void *); 177 int ehci_detach(struct ehci_softc *, int); 178 int ehci_activate(struct device *, int); 179 usbd_status ehci_reset(struct ehci_softc *); 180 181