Initial import from FreeBSD RELENG_4:
[dragonfly.git] / sys / bus / usb / uhcivar.h
1 /*      $NetBSD: uhcivar.h,v 1.21 2000/01/18 20:11:01 augustss Exp $    */
2 /*      $FreeBSD: src/sys/dev/usb/uhcivar.h,v 1.16.2.5 2000/10/31 23:23:29 n_hibma Exp $        */
3
4 /*
5  * Copyright (c) 1998 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) at
10  * Carlstedt Research & Technology.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  * 3. All advertising materials mentioning features or use of this software
21  *    must display the following acknowledgement:
22  *        This product includes software developed by the NetBSD
23  *        Foundation, Inc. and its contributors.
24  * 4. Neither the name of The NetBSD Foundation nor the names of its
25  *    contributors may be used to endorse or promote products derived
26  *    from this software without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
29  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
32  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38  * POSSIBILITY OF SUCH DAMAGE.
39  */
40
41 /*
42  * To avoid having 1024 TDs for each isochronous transfer we introduce
43  * a virtual frame list.  Every UHCI_VFRAMELIST_COUNT entries in the real
44  * frame list points to a non-active TD.  These, in turn, which form the 
45  * starts of the virtual frame list.  This also has the advantage that it 
46  * simplifies linking in/out TD/QH in the schedule.
47  * Furthermore, initially each of the inactive TDs point to an inactive
48  * QH that forms the start of the interrupt traffic for that slot.
49  * Each of these QHs point to the same QH that is the start of control
50  * traffic.
51  *
52  * UHCI_VFRAMELIST_COUNT should be a power of 2 and <= UHCI_FRAMELIST_COUNT.
53  */
54 #define UHCI_VFRAMELIST_COUNT 128
55
56 typedef struct uhci_soft_qh uhci_soft_qh_t;
57 typedef struct uhci_soft_td uhci_soft_td_t;
58
59 typedef union {
60         struct uhci_soft_qh *sqh;
61         struct uhci_soft_td *std;
62 } uhci_soft_td_qh_t;
63
64 /*
65  * An interrupt info struct contains the information needed to
66  * execute a requested routine when the controller generates an
67  * interrupt.  Since we cannot know which transfer generated
68  * the interrupt all structs are linked together so they can be
69  * searched at interrupt time.
70  */
71 typedef struct uhci_intr_info {
72         struct uhci_softc *sc;
73         usbd_xfer_handle xfer;
74         uhci_soft_td_t *stdstart;
75         uhci_soft_td_t *stdend;
76         LIST_ENTRY(uhci_intr_info) list;
77 #if defined(__FreeBSD__)
78         struct callout_handle timeout_handle;
79 #endif /* defined(__FreeBSD__) */
80 #ifdef DIAGNOSTIC
81         int isdone;
82 #endif
83 } uhci_intr_info_t;
84
85 /*
86  * Extra information that we need for a TD.
87  */
88 struct uhci_soft_td {
89         uhci_td_t td;                   /* The real TD, must be first */
90         uhci_soft_td_qh_t link;         /* soft version of the td_link field */
91         uhci_physaddr_t physaddr;       /* TD's physical address. */
92 };
93 /* 
94  * Make the size such that it is a multiple of UHCI_TD_ALIGN.  This way
95  * we can pack a number of soft TD together and have the real TD well
96  * aligned.
97  * NOTE: Minimum size is 32 bytes.
98  */
99 #define UHCI_STD_SIZE ((sizeof (struct uhci_soft_td) + UHCI_TD_ALIGN - 1) / UHCI_TD_ALIGN * UHCI_TD_ALIGN)
100 #define UHCI_STD_CHUNK 128 /*(PAGE_SIZE / UHCI_TD_SIZE)*/
101
102 /*
103  * Extra information that we need for a QH.
104  */
105 struct uhci_soft_qh {
106         uhci_qh_t qh;                   /* The real QH, must be first */
107         uhci_soft_qh_t *hlink;          /* soft version of qh_hlink */
108         uhci_soft_td_t *elink;          /* soft version of qh_elink */
109         uhci_physaddr_t physaddr;       /* QH's physical address. */
110         int pos;                        /* Timeslot position */
111         uhci_intr_info_t *intr_info;    /* Who to call on completion. */
112 /* XXX should try to shrink with 4 bytes to fit into 32 bytes */
113 };
114 /* See comment about UHCI_STD_SIZE. */
115 #define UHCI_SQH_SIZE ((sizeof (struct uhci_soft_qh) + UHCI_QH_ALIGN - 1) / UHCI_QH_ALIGN * UHCI_QH_ALIGN)
116 #define UHCI_SQH_CHUNK 128 /*(PAGE_SIZE / UHCI_QH_SIZE)*/
117
118 /*
119  * Information about an entry in the virtual frame list.
120  */
121 struct uhci_vframe {
122         uhci_soft_td_t *htd;            /* pointer to dummy TD */
123         uhci_soft_td_t *etd;            /* pointer to last TD */
124         uhci_soft_qh_t *hqh;            /* pointer to dummy QH */
125         uhci_soft_qh_t *eqh;            /* pointer to last QH */
126         u_int bandwidth;                /* max bandwidth used by this frame */
127 };
128
129 typedef struct uhci_softc {
130         struct usbd_bus sc_bus;         /* base device */
131         bus_space_tag_t iot;
132         bus_space_handle_t ioh;
133 #if defined(__FreeBSD__)
134         void *ih;
135
136         struct resource *io_res;
137         struct resource *irq_res;
138 #endif
139
140         uhci_physaddr_t *sc_pframes;
141         usb_dma_t sc_dma;
142         struct uhci_vframe sc_vframes[UHCI_VFRAMELIST_COUNT];
143
144         uhci_soft_qh_t *sc_ctl_start;   /* dummy QH for control */
145         uhci_soft_qh_t *sc_ctl_end;     /* last control QH */
146         uhci_soft_qh_t *sc_bulk_start;  /* dummy QH for bulk */
147         uhci_soft_qh_t *sc_bulk_end;    /* last bulk transfer */
148
149         uhci_soft_td_t *sc_freetds;     /* TD free list */
150         uhci_soft_qh_t *sc_freeqhs;     /* QH free list */
151
152         SIMPLEQ_HEAD(, usbd_xfer) sc_free_xfers; /* free xfers */
153
154         u_int8_t sc_addr;               /* device address */
155         u_int8_t sc_conf;               /* device configuration */
156
157         u_int8_t sc_saved_sof;
158         u_int16_t sc_saved_frnum;
159
160         char sc_isreset;
161         char sc_suspend;
162
163         LIST_HEAD(, uhci_intr_info) sc_intrhead;
164
165         /* Info for the root hub interrupt channel. */
166         int sc_ival;                    /* time between root hug intrs */
167         usbd_xfer_handle sc_has_timo;   /* root hub interrupt transfer */
168
169         char sc_vflock;                 /* for lock virtual frame list */
170 #define UHCI_HAS_LOCK 1
171 #define UHCI_WANT_LOCK 2
172
173         char sc_vendor[16];             /* vendor string for root hub */
174         int sc_id_vendor;               /* vendor ID for root hub */
175
176 #if defined(__NetBSD__)
177         void *sc_powerhook;             /* cookie from power hook */
178         void *sc_shutdownhook;          /* cookie from shutdown hook */
179 #endif
180
181         device_ptr_t sc_child;          /* /dev/usb device */
182 } uhci_softc_t;
183
184 usbd_status     uhci_init(uhci_softc_t *);
185 int             uhci_intr(void *);
186 #if defined(__NetBSD__) || defined(__OpenBSD__)
187 int             uhci_detach(uhci_softc_t *, int);
188 int             uhci_activate(device_ptr_t, enum devact);
189 #endif
190
191 void            uhci_shutdown(void *v);
192 void            uhci_power(int state, void *priv);
193