Annotation of src/sys/dev/usb/ehcivar.h, Revision 1.42.18.1
1.42.18.1! skrll 1: /* $NetBSD: ehcivar.h,v 1.42 2013/02/02 14:15:55 matt Exp $ */
1.1 augustss 2:
3: /*
1.4 augustss 4: * Copyright (c) 2001 The NetBSD Foundation, Inc.
1.1 augustss 5: * All rights reserved.
6: *
7: * This code is derived from software contributed to The NetBSD Foundation
8: * by Lennart Augustsson (lennart@augustsson.net).
9: *
10: * Redistribution and use in source and binary forms, with or without
11: * modification, are permitted provided that the following conditions
12: * are met:
13: * 1. Redistributions of source code must retain the above copyright
14: * notice, this list of conditions and the following disclaimer.
15: * 2. Redistributions in binary form must reproduce the above copyright
16: * notice, this list of conditions and the following disclaimer in the
17: * documentation and/or other materials provided with the distribution.
18: *
19: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29: * POSSIBILITY OF SUCH DAMAGE.
30: */
31:
1.41 christos 32: #ifndef _EHCIVAR_H_
33: #define _EHCIVAR_H_
34:
35: #include <sys/pool.h>
36:
1.7 augustss 37: typedef struct ehci_soft_qtd {
38: ehci_qtd_t qtd;
1.42.18.1! skrll 39: struct ehci_soft_qtd *nextqtd; /* mirrors nextqtd in TD */
! 40: ehci_physaddr_t physaddr; /* qTD's physical address */
! 41: usb_dma_t dma; /* qTD's DMA infos */
! 42: int offs; /* qTD's offset in usb_dma_t */
! 43: struct usbd_xfer *xfer; /* xfer back pointer */
! 44: uint16_t len;
1.7 augustss 45: } ehci_soft_qtd_t;
1.42 matt 46: #define EHCI_SQTD_ALIGN MAX(EHCI_QTD_ALIGN, CACHE_LINE_SIZE)
1.42.18.1! skrll 47: #define EHCI_SQTD_SIZE ((sizeof(struct ehci_soft_qtd) + EHCI_SQTD_ALIGN - 1) & -EHCI_SQTD_ALIGN)
1.7 augustss 48: #define EHCI_SQTD_CHUNK (EHCI_PAGE_SIZE / EHCI_SQTD_SIZE)
49:
50: typedef struct ehci_soft_qh {
51: ehci_qh_t qh;
52: struct ehci_soft_qh *next;
1.9 augustss 53: struct ehci_soft_qtd *sqtd;
1.7 augustss 54: ehci_physaddr_t physaddr;
1.42.18.1! skrll 55: usb_dma_t dma; /* QH's DMA infos */
! 56: int offs; /* QH's offset in usb_dma_t */
1.15 augustss 57: int islot;
1.7 augustss 58: } ehci_soft_qh_t;
1.42.18.1! skrll 59: #define EHCI_SQH_SIZE ((sizeof(struct ehci_soft_qh) + EHCI_QH_ALIGN - 1) / EHCI_QH_ALIGN * EHCI_QH_ALIGN)
1.7 augustss 60: #define EHCI_SQH_CHUNK (EHCI_PAGE_SIZE / EHCI_SQH_SIZE)
61:
1.32 jmcneill 62: typedef struct ehci_soft_itd {
1.42.18.1! skrll 63: union {
! 64: ehci_itd_t itd;
! 65: ehci_sitd_t sitd;
! 66: };
1.32 jmcneill 67: union {
68: struct {
1.42.18.1! skrll 69: /* soft_itds links in a periodic frame */
1.32 jmcneill 70: struct ehci_soft_itd *next;
71: struct ehci_soft_itd *prev;
72: } frame_list;
73: /* circular list of free itds */
74: LIST_ENTRY(ehci_soft_itd) free_list;
1.42.18.1! skrll 75: };
1.32 jmcneill 76: struct ehci_soft_itd *xfer_next; /* Next soft_itd in xfer */
77: ehci_physaddr_t physaddr;
78: usb_dma_t dma;
79: int offs;
80: int slot;
81: struct timeval t; /* store free time */
82: } ehci_soft_itd_t;
83: #define EHCI_ITD_SIZE ((sizeof(struct ehci_soft_itd) + EHCI_QH_ALIGN - 1) / EHCI_ITD_ALIGN * EHCI_ITD_ALIGN)
84: #define EHCI_ITD_CHUNK (EHCI_PAGE_SIZE / EHCI_ITD_SIZE)
85:
1.42.18.1! skrll 86: #define ehci_soft_sitd_t ehci_soft_itd_t
! 87: #define ehci_soft_sitd ehci_soft_itd
! 88: #define sc_softsitds sc_softitds
! 89: #define EHCI_SITD_SIZE ((sizeof(struct ehci_soft_sitd) + EHCI_QH_ALIGN - 1) / EHCI_SITD_ALIGN * EHCI_SITD_ALIGN)
! 90: #define EHCI_SITD_CHUNK (EHCI_PAGE_SIZE / EHCI_SITD_SIZE)
! 91:
1.11 augustss 92: struct ehci_xfer {
1.42.18.1! skrll 93: struct usbd_xfer ex_xfer;
! 94: struct usb_task ex_aborttask;
! 95: TAILQ_ENTRY(ehci_xfer) ex_next; /* list of active xfers */
! 96: enum {
! 97: EX_NONE,
! 98: EX_CTRL,
! 99: EX_BULK,
! 100: EX_INTR,
! 101: EX_ISOC,
! 102: EX_FS_ISOC
! 103: } ex_type;
! 104: /* ctrl/bulk/intr */
! 105: struct {
! 106: ehci_soft_qtd_t **ex_sqtds;
! 107: size_t ex_nsqtd;
! 108: };
! 109: union {
! 110: /* ctrl */
! 111: struct {
! 112: ehci_soft_qtd_t *ex_setup;
! 113: ehci_soft_qtd_t *ex_data;
! 114: ehci_soft_qtd_t *ex_status;
! 115: };
! 116: /* bulk/intr */
! 117: struct {
! 118: ehci_soft_qtd_t *ex_sqtdstart;
! 119: ehci_soft_qtd_t *ex_sqtdend;
! 120: };
! 121: /* isoc */
! 122: struct {
! 123: ehci_soft_itd_t *ex_itdstart;
! 124: ehci_soft_itd_t *ex_itdend;
! 125: };
! 126: /* split (aka fs) isoc */
! 127: struct {
! 128: ehci_soft_sitd_t *ex_sitdstart;
! 129: ehci_soft_sitd_t *ex_sitdend;
! 130: };
! 131: };
! 132: bool ex_isdone; /* used only when DIAGNOSTIC is defined */
1.11 augustss 133: };
1.42.18.1! skrll 134:
! 135: #define EHCI_BUS2SC(bus) ((bus)->ub_hcpriv)
! 136: #define EHCI_PIPE2SC(pipe) EHCI_BUS2SC((pipe)->up_dev->ud_bus)
! 137: #define EHCI_XFER2SC(xfer) EHCI_BUS2SC((xfer)->ux_bus)
! 138: #define EHCI_EPIPE2SC(epipe) EHCI_BUS2SC((epipe)->pipe.up_dev->ud_bus)
! 139:
! 140: #define EHCI_XFER2EXFER(xfer) ((struct ehci_xfer *)(xfer))
! 141:
! 142: #define EHCI_XFER2EPIPE(xfer) ((struct ehci_pipe *)((xfer)->ux_pipe))
! 143: #define EHCI_PIPE2EPIPE(pipe) ((struct ehci_pipe *)(pipe))
1.11 augustss 144:
1.15 augustss 145: /* Information about an entry in the interrupt list. */
146: struct ehci_soft_islot {
147: ehci_soft_qh_t *sqh; /* Queue Head. */
148: };
149:
150: #define EHCI_FRAMELIST_MAXCOUNT 1024
151: #define EHCI_IPOLLRATES 8 /* Poll rates (1ms, 2, 4, 8 .. 128) */
152: #define EHCI_INTRQHS ((1 << EHCI_IPOLLRATES) - 1)
1.18 augustss 153: #define EHCI_MAX_POLLRATE (1 << (EHCI_IPOLLRATES - 1))
1.15 augustss 154: #define EHCI_IQHIDX(lev, pos) \
155: ((((pos) & ((1 << (lev)) - 1)) | (1 << (lev))) - 1)
156: #define EHCI_ILEV_IVAL(lev) (1 << (lev))
157:
1.7 augustss 158:
159: #define EHCI_HASH_SIZE 128
1.3 augustss 160: #define EHCI_COMPANION_MAX 8
1.7 augustss 161:
1.32 jmcneill 162: #define EHCI_FREE_LIST_INTERVAL 100
163:
1.1 augustss 164: typedef struct ehci_softc {
1.29 drochner 165: device_t sc_dev;
1.40 mrg 166: kmutex_t sc_lock;
167: kmutex_t sc_intr_lock;
168: kcondvar_t sc_doorbell;
169: void *sc_doorbell_si;
170: void *sc_pcd_si;
1.29 drochner 171: struct usbd_bus sc_bus;
1.1 augustss 172: bus_space_tag_t iot;
173: bus_space_handle_t ioh;
174: bus_size_t sc_size;
1.2 augustss 175: u_int sc_offs; /* offset to operational regs */
1.23 xtraeme 176: int sc_flags; /* misc flags */
177: #define EHCIF_DROPPED_INTR_WORKAROUND 0x01
1.38 matt 178: #define EHCIF_ETTF 0x02 /* Emb. Transaction Translater func. */
1.1 augustss 179:
1.19 augustss 180: char sc_vendor[32]; /* vendor string for root hub */
1.1 augustss 181: int sc_id_vendor; /* vendor ID for root hub */
182:
1.42.18.1! skrll 183: uint32_t sc_cmd; /* shadow of cmd reg during suspend */
1.1 augustss 184:
1.3 augustss 185: u_int sc_ncomp;
1.5 augustss 186: u_int sc_npcomp;
1.29 drochner 187: device_t sc_comps[EHCI_COMPANION_MAX];
1.3 augustss 188:
189: usb_dma_t sc_fldma;
1.15 augustss 190: ehci_link_t *sc_flist;
1.3 augustss 191: u_int sc_flsize;
1.15 augustss 192: u_int sc_rand; /* XXX need proper intr scheduling */
193:
194: struct ehci_soft_islot sc_islots[EHCI_INTRQHS];
1.3 augustss 195:
1.42.18.1! skrll 196: /*
! 197: * an array matching sc_flist, but with software pointers,
1.32 jmcneill 198: * not hardware address pointers
199: */
200: struct ehci_soft_itd **sc_softitds;
201:
1.33 jmcneill 202: TAILQ_HEAD(, ehci_xfer) sc_intrhead;
1.11 augustss 203:
1.7 augustss 204: ehci_soft_qh_t *sc_freeqhs;
205: ehci_soft_qtd_t *sc_freeqtds;
1.32 jmcneill 206: LIST_HEAD(sc_freeitds, ehci_soft_itd) sc_freeitds;
1.42.18.1! skrll 207: LIST_HEAD(sc_freesitds, ehci_soft_sitd) sc_freesitds;
1.7 augustss 208:
1.4 augustss 209: int sc_noport;
1.42.18.1! skrll 210: uint8_t sc_hasppc; /* has Port Power Control */
! 211: uint8_t sc_istthreshold; /* ISOC Scheduling Threshold (uframes) */
! 212: struct usbd_xfer *sc_intrxfer;
1.21 augustss 213: char sc_isreset[EHCI_MAX_PORTS];
1.12 augustss 214: char sc_softwake;
1.40 mrg 215: kcondvar_t sc_softwake_cv;
1.5 augustss 216:
1.42.18.1! skrll 217: uint32_t sc_eintrs;
1.9 augustss 218: ehci_soft_qh_t *sc_async_head;
1.4 augustss 219:
1.41 christos 220: pool_cache_t sc_xferpool; /* free xfer pool */
1.8 augustss 221:
1.34 dyoung 222: struct callout sc_tmo_intrlist;
1.4 augustss 223:
1.34 dyoung 224: device_t sc_child; /* /dev/usb# device */
1.4 augustss 225: char sc_dying;
1.37 kiyohara 226:
227: void (*sc_vendor_init)(struct ehci_softc *);
228: int (*sc_vendor_port_status)(struct ehci_softc *, uint32_t, int);
1.1 augustss 229: } ehci_softc_t;
1.2 augustss 230:
1.3 augustss 231: #define EREAD1(sc, a) bus_space_read_1((sc)->iot, (sc)->ioh, (a))
232: #define EREAD2(sc, a) bus_space_read_2((sc)->iot, (sc)->ioh, (a))
233: #define EREAD4(sc, a) bus_space_read_4((sc)->iot, (sc)->ioh, (a))
234: #define EWRITE1(sc, a, x) bus_space_write_1((sc)->iot, (sc)->ioh, (a), (x))
235: #define EWRITE2(sc, a, x) bus_space_write_2((sc)->iot, (sc)->ioh, (a), (x))
236: #define EWRITE4(sc, a, x) bus_space_write_4((sc)->iot, (sc)->ioh, (a), (x))
1.2 augustss 237: #define EOREAD1(sc, a) bus_space_read_1((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a))
238: #define EOREAD2(sc, a) bus_space_read_2((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a))
239: #define EOREAD4(sc, a) bus_space_read_4((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a))
240: #define EOWRITE1(sc, a, x) bus_space_write_1((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a), (x))
241: #define EOWRITE2(sc, a, x) bus_space_write_2((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a), (x))
242: #define EOWRITE4(sc, a, x) bus_space_write_4((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a), (x))
1.1 augustss 243:
1.42.18.1! skrll 244: int ehci_init(ehci_softc_t *);
1.1 augustss 245: int ehci_intr(void *);
246: int ehci_detach(ehci_softc_t *, int);
1.27 dyoung 247: int ehci_activate(device_t, enum devact);
248: void ehci_childdet(device_t, device_t);
1.36 dyoung 249: bool ehci_suspend(device_t, const pmf_qual_t *);
250: bool ehci_resume(device_t, const pmf_qual_t *);
1.28 dyoung 251: bool ehci_shutdown(device_t, int);
1.41 christos 252:
253: #endif /* _EHCIVAR_H_ */
CVSweb <webmaster@jp.NetBSD.org>