]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - sys/dev/usb/controller/ohci.h
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / sys / dev / usb / controller / ohci.h
1 /* $FreeBSD$ */
2 /*-
3  * Copyright (c) 1998 The NetBSD Foundation, Inc.
4  * All rights reserved.
5  *
6  * This code is derived from software contributed to The NetBSD Foundation
7  * by Lennart Augustsson (lennart@augustsson.net) at
8  * Carlstedt Research & Technology.
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  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *        This product includes software developed by the NetBSD
21  *        Foundation, Inc. and its contributors.
22  * 4. Neither the name of The NetBSD Foundation nor the names of its
23  *    contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36  * POSSIBILITY OF SUCH DAMAGE.
37  */
38
39 #ifndef _OHCI_H_
40 #define _OHCI_H_
41
42 #define OHCI_MAX_DEVICES MIN(USB_MAX_DEVICES, 128)
43
44 #define OHCI_NO_INTRS           32
45 #define OHCI_HCCA_SIZE          256
46
47 /* Structures alignment (bytes) */
48 #define OHCI_HCCA_ALIGN         256
49 #define OHCI_ED_ALIGN           16
50 #define OHCI_TD_ALIGN           16
51 #define OHCI_ITD_ALIGN          32
52
53 #define OHCI_PAGE_SIZE          0x1000
54 #define OHCI_PAGE(x)            ((x) &~ 0xfff)
55 #define OHCI_PAGE_OFFSET(x)     ((x) & 0xfff)
56 #define OHCI_PAGE_MASK(x)       ((x) & 0xfff)
57
58 #if     ((USB_PAGE_SIZE < OHCI_ED_ALIGN) || (OHCI_ED_ALIGN == 0) ||     \
59         (USB_PAGE_SIZE < OHCI_TD_ALIGN) || (OHCI_TD_ALIGN == 0) ||      \
60         (USB_PAGE_SIZE < OHCI_ITD_ALIGN) || (OHCI_ITD_ALIGN == 0) ||    \
61         (USB_PAGE_SIZE < OHCI_PAGE_SIZE) || (OHCI_PAGE_SIZE == 0))
62 #error  "Invalid USB page size!"
63 #endif
64
65 #define OHCI_VIRTUAL_FRAMELIST_COUNT 128/* dummy */
66
67 #if (OHCI_VIRTUAL_FRAMELIST_COUNT < USB_MAX_FS_ISOC_FRAMES_PER_XFER)
68 #error "maximum number of full-speed isochronous frames is higher than supported!"
69 #endif
70
71 struct ohci_hcca {
72         volatile uint32_t hcca_interrupt_table[OHCI_NO_INTRS];
73         volatile uint32_t hcca_frame_number;
74         volatile uint32_t hcca_done_head;
75 #define OHCI_DONE_INTRS         1
76 } __aligned(OHCI_HCCA_ALIGN);
77
78 typedef struct ohci_hcca ohci_hcca_t;
79
80 struct ohci_ed {
81         volatile uint32_t ed_flags;
82 #define OHCI_ED_GET_FA(s)       ((s) & 0x7f)
83 #define OHCI_ED_ADDRMASK        0x0000007f
84 #define OHCI_ED_SET_FA(s)       (s)
85 #define OHCI_ED_GET_EN(s)       (((s) >> 7) & 0xf)
86 #define OHCI_ED_SET_EN(s)       ((s) << 7)
87 #define OHCI_ED_DIR_MASK        0x00001800
88 #define OHCI_ED_DIR_TD          0x00000000
89 #define OHCI_ED_DIR_OUT         0x00000800
90 #define OHCI_ED_DIR_IN          0x00001000
91 #define OHCI_ED_SPEED           0x00002000
92 #define OHCI_ED_SKIP            0x00004000
93 #define OHCI_ED_FORMAT_GEN      0x00000000
94 #define OHCI_ED_FORMAT_ISO      0x00008000
95 #define OHCI_ED_GET_MAXP(s)     (((s) >> 16) & 0x07ff)
96 #define OHCI_ED_SET_MAXP(s)     ((s) << 16)
97 #define OHCI_ED_MAXPMASK        (0x7ff << 16)
98         volatile uint32_t ed_tailp;
99         volatile uint32_t ed_headp;
100 #define OHCI_HALTED             0x00000001
101 #define OHCI_TOGGLECARRY        0x00000002
102 #define OHCI_HEADMASK           0xfffffffc
103         volatile uint32_t ed_next;
104 /*
105  * Extra information needed:
106  */
107         struct ohci_ed *next;
108         struct ohci_ed *prev;
109         struct ohci_ed *obj_next;
110         struct usb_page_cache *page_cache;
111         uint32_t ed_self;
112 } __aligned(OHCI_ED_ALIGN);
113
114 typedef struct ohci_ed ohci_ed_t;
115
116 struct ohci_td {
117         volatile uint32_t td_flags;
118 #define OHCI_TD_R               0x00040000      /* Buffer Rounding  */
119 #define OHCI_TD_DP_MASK         0x00180000      /* Direction / PID */
120 #define OHCI_TD_SETUP           0x00000000
121 #define OHCI_TD_OUT             0x00080000
122 #define OHCI_TD_IN              0x00100000
123 #define OHCI_TD_GET_DI(x)       (((x) >> 21) & 7)       /* Delay Interrupt */
124 #define OHCI_TD_SET_DI(x)       ((x) << 21)
125 #define OHCI_TD_NOINTR          0x00e00000
126 #define OHCI_TD_INTR_MASK       0x00e00000
127 #define OHCI_TD_TOGGLE_CARRY    0x00000000
128 #define OHCI_TD_TOGGLE_0        0x02000000
129 #define OHCI_TD_TOGGLE_1        0x03000000
130 #define OHCI_TD_TOGGLE_MASK     0x03000000
131 #define OHCI_TD_GET_EC(x)       (((x) >> 26) & 3)       /* Error Count */
132 #define OHCI_TD_GET_CC(x)       ((x) >> 28)     /* Condition Code */
133 #define OHCI_TD_SET_CC(x)       ((x) << 28)
134 #define OHCI_TD_NOCC            0xf0000000
135         volatile uint32_t td_cbp;       /* Current Buffer Pointer */
136         volatile uint32_t td_next;      /* Next TD */
137 #define OHCI_TD_NEXT_END        0
138         volatile uint32_t td_be;        /* Buffer End */
139 /*
140  * Extra information needed:
141  */
142         struct ohci_td *obj_next;
143         struct ohci_td *alt_next;
144         struct usb_page_cache *page_cache;
145         uint32_t td_self;
146         uint16_t len;
147 } __aligned(OHCI_TD_ALIGN);
148
149 typedef struct ohci_td ohci_td_t;
150
151 struct ohci_itd {
152         volatile uint32_t itd_flags;
153 #define OHCI_ITD_GET_SF(x)      ((x) & 0x0000ffff)
154 #define OHCI_ITD_SET_SF(x)      ((x) & 0xffff)
155 #define OHCI_ITD_GET_DI(x)      (((x) >> 21) & 7)       /* Delay Interrupt */
156 #define OHCI_ITD_SET_DI(x)      ((x) << 21)
157 #define OHCI_ITD_NOINTR         0x00e00000
158 #define OHCI_ITD_GET_FC(x)      ((((x) >> 24) & 7)+1)   /* Frame Count */
159 #define OHCI_ITD_SET_FC(x)      (((x)-1) << 24)
160 #define OHCI_ITD_GET_CC(x)      ((x) >> 28)     /* Condition Code */
161 #define OHCI_ITD_NOCC           0xf0000000
162 #define OHCI_ITD_NOFFSET        8
163         volatile uint32_t itd_bp0;      /* Buffer Page 0 */
164         volatile uint32_t itd_next;     /* Next ITD */
165         volatile uint32_t itd_be;       /* Buffer End */
166         volatile uint16_t itd_offset[OHCI_ITD_NOFFSET]; /* Buffer offsets and
167                                                          * Status */
168 #define OHCI_ITD_PAGE_SELECT    0x00001000
169 #define OHCI_ITD_MK_OFFS(len)   (0xe000 | ((len) & 0x1fff))
170 #define OHCI_ITD_PSW_LENGTH(x)  ((x) & 0xfff)   /* Transfer length */
171 #define OHCI_ITD_PSW_GET_CC(x)  ((x) >> 12)     /* Condition Code */
172 /*
173  * Extra information needed:
174  */
175         struct ohci_itd *obj_next;
176         struct usb_page_cache *page_cache;
177         uint32_t itd_self;
178         uint8_t frames;
179 } __aligned(OHCI_ITD_ALIGN);
180
181 typedef struct ohci_itd ohci_itd_t;
182
183 #define OHCI_CC_NO_ERROR                0
184 #define OHCI_CC_CRC                     1
185 #define OHCI_CC_BIT_STUFFING            2
186 #define OHCI_CC_DATA_TOGGLE_MISMATCH    3
187 #define OHCI_CC_STALL                   4
188 #define OHCI_CC_DEVICE_NOT_RESPONDING   5
189 #define OHCI_CC_PID_CHECK_FAILURE       6
190 #define OHCI_CC_UNEXPECTED_PID          7
191 #define OHCI_CC_DATA_OVERRUN            8
192 #define OHCI_CC_DATA_UNDERRUN           9
193 #define OHCI_CC_BUFFER_OVERRUN          12
194 #define OHCI_CC_BUFFER_UNDERRUN         13
195 #define OHCI_CC_NOT_ACCESSED            15
196
197 /* Some delay needed when changing certain registers. */
198 #define OHCI_ENABLE_POWER_DELAY         5
199 #define OHCI_READ_DESC_DELAY            5
200
201 #define OHCI_NO_EDS                     (2*OHCI_NO_INTRS)
202
203 struct ohci_hw_softc {
204         struct usb_page_cache hcca_pc;
205         struct usb_page_cache ctrl_start_pc;
206         struct usb_page_cache bulk_start_pc;
207         struct usb_page_cache isoc_start_pc;
208         struct usb_page_cache intr_start_pc[OHCI_NO_EDS];
209
210         struct usb_page hcca_pg;
211         struct usb_page ctrl_start_pg;
212         struct usb_page bulk_start_pg;
213         struct usb_page isoc_start_pg;
214         struct usb_page intr_start_pg[OHCI_NO_EDS];
215 };
216
217 struct ohci_config_desc {
218         struct usb_config_descriptor confd;
219         struct usb_interface_descriptor ifcd;
220         struct usb_endpoint_descriptor endpd;
221 } __packed;
222
223 union ohci_hub_desc {
224         struct usb_status stat;
225         struct usb_port_status ps;
226         struct usb_hub_descriptor hubd;
227         uint8_t temp[128];
228 };
229
230 typedef struct ohci_softc {
231         struct ohci_hw_softc sc_hw;
232         struct usb_bus sc_bus;          /* base device */
233         struct usb_callout sc_tmo_rhsc;
234         union ohci_hub_desc sc_hub_desc;
235
236         struct usb_device *sc_devices[OHCI_MAX_DEVICES];
237         struct resource *sc_io_res;
238         struct resource *sc_irq_res;
239         struct ohci_hcca *sc_hcca_p;
240         struct ohci_ed *sc_ctrl_p_last;
241         struct ohci_ed *sc_bulk_p_last;
242         struct ohci_ed *sc_isoc_p_last;
243         struct ohci_ed *sc_intr_p_last[OHCI_NO_EDS];
244         void   *sc_intr_hdl;
245         device_t sc_dev;
246         bus_size_t sc_io_size;
247         bus_space_tag_t sc_io_tag;
248         bus_space_handle_t sc_io_hdl;
249
250         uint32_t sc_eintrs;             /* enabled interrupts */
251         uint32_t sc_control;            /* Preserved during suspend/standby */
252         uint32_t sc_intre;
253
254         uint16_t sc_intr_stat[OHCI_NO_EDS];
255         uint16_t sc_id_vendor;
256
257         uint8_t sc_noport;
258         uint8_t sc_addr;                /* device address */
259         uint8_t sc_conf;                /* device configuration */
260         uint8_t sc_hub_idata[32];
261
262         char    sc_vendor[16];
263
264 } ohci_softc_t;
265
266 usb_bus_mem_cb_t ohci_iterate_hw_softc;
267
268 usb_error_t ohci_init(ohci_softc_t *sc);
269 void    ohci_detach(struct ohci_softc *sc);
270 void    ohci_suspend(ohci_softc_t *sc);
271 void    ohci_resume(ohci_softc_t *sc);
272 void    ohci_interrupt(ohci_softc_t *sc);
273
274 #endif                                  /* _OHCI_H_ */