Fixed compatibility of output.
[AROS.git] / workbench / devs / USB / drivers / OHCI / ohci.h
blob23af3163d533621cd158e95909ea04673429307c
1 #ifndef OHCI_H_
2 #define OHCI_H_
4 /*
5 Copyright (C) 2006 by Michal Schulz
6 $Id$
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU Library General Public License as
10 published by the Free Software Foundation; either version 2 of the
11 License, or (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU Library General Public
19 License along with this program; if not, write to the
20 Free Software Foundation, Inc.,
21 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 #include <inttypes.h>
26 #include <aros/asmcall.h>
27 #include <aros/macros.h>
29 #include <exec/semaphores.h>
30 #include <devices/timer.h>
32 #include LC_LIBDEFS_FILE
34 #ifndef BIG_ENDIAN_OHCI
35 #define BIG_ENDIAN_OHCI 0
36 #endif
38 #if BIG_ENDIAN_OHCI
39 #define AROS_LONG2OHCI(x) (AROS_LONG2BE(x))
40 #define AROS_WORD2OHCI(x) (AROS_WORD2BE(x))
41 #define AROS_OHCI2LONG(x) (AROS_BE2LONG(x))
42 #define AROS_OHCI2WORD(x) (AROS_BE2WORD(x))
43 #else
44 #define AROS_LONG2OHCI(x) (AROS_LONG2LE(x))
45 #define AROS_WORD2OHCI(x) (AROS_WORD2LE(x))
46 #define AROS_OHCI2LONG(x) (AROS_LE2LONG(x))
47 #define AROS_OHCI2WORD(x) (AROS_LE2WORD(x))
48 #endif
50 #define mmio(var) (*(volatile uint32_t *)&(var))
52 typedef struct ohci_registers {
53 uint32_t HcRevision;
54 uint32_t HcControl;
55 uint32_t HcCommandStatus;
56 uint32_t HcInterruptStatus;
57 uint32_t HcInterruptEnable;
58 uint32_t HcInterruptDisable;
59 uint32_t HcHCCA;
60 uint32_t HcPeriodCurrentED;
61 uint32_t HcControlHeadED;
62 uint32_t HcControlCurrentED;
63 uint32_t HcBulkHeadED;
64 uint32_t HcBulkCurrentED;
65 uint32_t HcDoneHead;
66 uint32_t HcFmInterval;
67 uint32_t HcFmRemaining;
68 uint32_t HcFmNumber;
69 uint32_t HcPeriodicStart;
70 uint32_t HcLSThreshold;
71 uint32_t HcRhDescriptorA;
72 uint32_t HcRhDescriptorB;
73 uint32_t HcRhStatus;
74 uint32_t HcRhPortStatus[0];
75 } ohci_registers_t;
77 /* HcControl */
78 #define HC_CTRL_CBSR_MASK 0x00000003
79 #define HC_CTRL_CBSR_1_1 0x00000000
80 #define HC_CTRL_CBSR_1_2 0x00000001
81 #define HC_CTRL_CBSR_1_3 0x00000002
82 #define HC_CTRL_CBSR_1_4 0x00000003
83 #define HC_CTRL_PLE 0x00000004
84 #define HC_CTRL_IE 0x00000008
85 #define HC_CTRL_CLE 0x00000010
86 #define HC_CTRL_BLE 0x00000020
87 #define HC_CTRL_HCFS_MASK 0x000000c0
88 #define HC_CTRL_HCFS_RESET 0x00000000
89 #define HC_CTRL_HCFS_RESUME 0x00000040
90 #define HC_CTRL_HCFS_OPERATIONAL 0x00000080
91 #define HC_CTRL_HCFS_SUSPENDED 0x000000c0
92 #define HC_CTRL_IR 0x00000100
93 #define HC_CTRL_RWC 0x00000200
94 #define HC_CTRL_RWE 0x00000400
96 /* HcCommandStatus */
97 #define HC_CS_HCR 0x00000001
98 #define HC_CS_CLF 0x00000002
99 #define HC_CS_BLF 0x00000004
100 #define HC_CS_OCR 0x00000008
101 #define HC_CS_SOC_MASK 0x00030000
103 /* HcInterruptStatus, HcInterruptDisable */
104 #define HC_INTR_SO 0x00000001
105 #define HC_INTR_WDH 0x00000002
106 #define HC_INTR_SF 0x00000004
107 #define HC_INTR_RD 0x00000008
108 #define HC_INTR_UE 0x00000010
109 #define HC_INTR_FNO 0x00000020
110 #define HC_INTR_RHSC 0x00000040
111 #define HC_INTR_OC 0x40000000
112 #define HC_INTR_MIE 0x80000000
114 /* HcFmInterval */
115 #define HC_FM_GET_IVAL(v) ((v) & 0x3fff)
116 #define HC_FM_GET_FSMPS(v) (((v) >> 16) & 0x7fff)
117 #define HC_FM_FIT 0x80000000
119 #define HC_FM_FSMPS(v) ((((v)-210)*6/7) << 16)
120 #define HC_PERIODIC(v) ((v)*9/10)
122 /* HcRhDescriptorA */
123 #define HC_RHA_GET_NDP(v) ((v) & 0xff)
124 #define HC_RHA_PSM 0x00000100
125 #define HC_RHA_NPS 0x00000200
126 #define HC_RHA_DT 0x00000400
127 #define HC_RHA_OCPM 0x00000800
128 #define HC_RHA_NOCP 0x00001000
129 #define HC_RHA_GET_POTPGT(v) ((v) >> 24)
131 /* HcRhStatus */
132 #define HC_RHS_LPS 0x00000001
133 #define HC_RHS_OCI 0x00000002
134 #define HC_RHS_DRWE 0x00008000
135 #define HC_RHS_LPSC 0x00010000
136 #define HC_RHS_OCIC 0x00020000
137 #define HC_RHS_CRWE 0x80000000
139 /* HcRhPortStatus */
140 #define HC_PS_CCS 0x00000001
141 #define HC_PS_PES 0x00000002
142 #define HC_PS_PSS 0x00000004
143 #define HC_PS_POCI 0x00000008
144 #define HC_PS_PRS 0x00000010
145 #define HC_PS_PPS 0x00000100
146 #define HC_PS_LSDA 0x00000200
147 #define HC_PS_CSC 0x00010000
148 #define HC_PS_PESC 0x00020000
149 #define HC_PS_PSSC 0x00040000
150 #define HC_PS_OCIC 0x00080000
151 #define HC_PS_PRSC 0x00100000
153 typedef struct ohci_pipe ohci_pipe_t;
155 typedef struct ohci_hcca {
156 uint32_t hccaIntrTab[32];
157 //#if AROS_BIG_ENDIAN
158 // uint16_t pad;
159 // uint16_t hccaFrNum;
160 //#else
161 uint16_t hccaFrNum;
162 uint16_t pad;
163 //#endif
164 uint32_t hccaDoneHead;
165 uint8_t hccaRsvd[116];
166 } __attribute__((packed)) ohci_hcca_t;
168 typedef struct ohci_ed {
169 uint32_t edFlags;
170 uint32_t edTailP;
171 uint32_t edHeadP;
172 uint32_t edNextED;
173 ohci_pipe_t *edPipe;
174 uint32_t edUsage;
175 } __attribute__((aligned(32))) ohci_ed_t;
177 #define ED_FA_MASK 0x0000007f
178 #define ED_EN_MASK 0x00000780
179 #define ED_D_MASK 0x00001800
180 #define ED_S 0x00002000
181 #define ED_K 0x00004000
182 #define ED_F 0x00008000
183 #define ED_MPS_MASK 0x07ff0000
184 #define ED_C 0x00000002
185 #define ED_H 0x00000001
187 #define ED_GET_USAGE(ed) ((ed)->edUsage)
188 #define ED_SET_USAGE(ed,u) ((ed)->edUsage = (u))
190 typedef struct ohci_td {
191 uint32_t tdFlags;
192 uint32_t tdCurrentBufferPointer;
193 uint32_t tdNextTD;
194 uint32_t tdBufferEnd;
195 ohci_pipe_t *tdPipe;
196 } __attribute__((aligned(32))) ohci_td_t;
198 #define TD_R 0x00040000
199 #define TD_DP_MASK 0x00180000
200 #define TD_DI_MASK 0x00e00000
201 #define TD_T_MASK 0x03000000
202 #define TD_EC_MASK 0x0c000000
203 #define TD_CC_MASK 0xf0000000
205 #define HC_FSMPS(i) (((i-210) * 6 / 7)<<16)
207 #define CLID_Drv_USB_OHCI "Bus::Drv::OHCI"
208 #define IID_Drv_USB_OHCI "Bus::Drv::OHCI"
210 #undef HiddPCIDeviceAttrBase
211 #undef HiddUSBDeviceAttrBase
212 #undef HiddUSBHubAttrBase
213 #undef HiddUSBDrvAttrBase
214 #undef HiddOHCIAttrBase
215 #undef HiddAttrBase
217 #define HiddPCIDeviceAttrBase (SD(cl)->HiddPCIDeviceAB)
218 #define HiddUSBDeviceAttrBase (SD(cl)->HiddUSBDeviceAB)
219 #define HiddUSBHubAttrBase (SD(cl)->HiddUSBHubAB)
220 #define HiddUSBDrvAttrBase (SD(cl)->HiddUSBDrvAB)
221 #define HiddOHCIAttrBase (SD(cl)->HiddOHCIAB)
222 #define HiddAttrBase (SD(cl)->HiddAB)
224 #define MAX_OHCI_DEVICES 8
226 typedef struct ohci_intr {
227 struct MinNode node;
228 struct Interrupt *intr;
229 ohci_td_t *td;
230 void *buffer;
231 uint32_t length;
232 } ohci_intr_t;
234 struct ohci_pipe {
235 struct Node node;
236 struct SignalSemaphore lock;
238 ohci_intr_t *interrupt;
239 ohci_ed_t *ed;
240 ohci_ed_t *location;
242 ohci_td_t *tail;
244 uint16_t maxpacket;
245 uint8_t type;
246 uint8_t interval;
247 uint8_t endpoint;
248 uint8_t address;
250 struct timerequest *timeout;
251 uint32_t timeoutVal;
252 struct Task *sigTask;
253 uint8_t signal;
255 uint32_t errorCode;
258 struct ohci_staticdata
260 OOP_Class *ohciClass;
262 OOP_Object *usb;
263 OOP_Object *pci;
265 OOP_AttrBase HiddPCIDeviceAB;
266 OOP_AttrBase HiddUSBDeviceAB;
267 OOP_AttrBase HiddUSBHubAB;
268 OOP_AttrBase HiddUSBDrvAB;
269 OOP_AttrBase HiddOHCIAB;
270 OOP_AttrBase HiddAB;
272 void *memPool;
274 struct SignalSemaphore tdLock;
275 struct List tdList;
277 uint8_t numDevices;
278 intptr_t ramBase[MAX_OHCI_DEVICES];
279 uint8_t numPorts[MAX_OHCI_DEVICES];
280 uint8_t irqNum[MAX_OHCI_DEVICES];
281 OOP_Object *pciDevice[MAX_OHCI_DEVICES];
282 OOP_Object *pciDriver[MAX_OHCI_DEVICES];
283 OOP_Object *ohciDevice[MAX_OHCI_DEVICES];
286 struct ohcibase
288 struct Library LibNode;
289 struct ohci_staticdata sd;
292 typedef struct ohci_data {
293 struct ohci_staticdata *sd;
294 volatile ohci_registers_t *regs;
295 volatile ohci_hcca_t *hcca;
296 usb_hub_descriptor_t hubDescr;
297 uint8_t running;
298 uint8_t pendingRHSC;
300 struct List intList;
301 struct Interrupt *tmp;
303 struct MsgPort timerPort;
304 struct Interrupt timerInt;
305 struct timerequest *timerReq;
307 struct timerequest *tr;
309 struct Interrupt irqHandler;
310 intptr_t irqNum;
312 OOP_Object *pciDriver;
313 OOP_Object *pciDevice;
315 ohci_ed_t *ctrl_head;
316 ohci_ed_t *bulk_head;
317 ohci_ed_t *isoc_head;
319 ohci_ed_t *int01;
320 ohci_ed_t *int02[2];
321 ohci_ed_t *int04[4];
322 ohci_ed_t *int08[8];
323 ohci_ed_t *int16[16];
324 ohci_ed_t *int32[32];
326 } ohci_data_t;
328 typedef struct td_node {
329 struct MinNode tdNode;
330 uint32_t tdBitmap[4];
331 ohci_td_t *tdPage;
332 } td_node_t;
334 #define BASE(lib)((struct ohcibase*)(lib))
335 #define SD(cl) (&BASE(cl->UserData)->sd)
337 #define METHOD(base, id, name) \
338 base ## __ ## id ## __ ## name (OOP_Class *cl, OOP_Object *o, struct p ## id ## _ ## name *msg)
340 enum {
341 aoHidd_OHCI_MemBase,
342 aoHidd_OHCI_PCIDriver,
343 aoHidd_OHCI_PCIDevice,
344 aoHidd_OHCI_IRQ,
346 num_Hidd_OHCI_Attrs
349 #define aHidd_OHCI_MemBase (HiddOHCIAttrBase + aoHidd_OHCI_MemBase)
350 #define aHidd_OHCI_PCIDriver (HiddOHCIAttrBase + aoHidd_OHCI_PCIDriver)
351 #define aHidd_OHCI_PCIDevice (HiddOHCIAttrBase + aoHidd_OHCI_PCIDevice)
352 #define aHidd_OHCI_IRQ (HiddOHCIAttrBase + aoHidd_OHCI_IRQ)
353 #define IS_OHCI_ATTR(attr, idx) (((idx)=(attr)-HiddOHCIAttrBase) < num_Hidd_OHCI_Attrs)
355 #define PCI_BASE_CLASS_SERIAL 0x0c
356 #define PCI_SUB_CLASS_USB 0x03
357 #define PCI_INTERFACE_OHCI 0x10
359 ohci_td_t *ohci_AllocTD(OOP_Class *cl, OOP_Object *o);
360 ohci_ed_t *ohci_AllocED(OOP_Class *cl, OOP_Object *o);
361 void ohci_FreeTDQuick(ohci_data_t *ohci, ohci_td_t *td);
362 void ohci_FreeEDQuick(ohci_data_t *ohci, ohci_ed_t *ed);
363 void ohci_FreeTD(OOP_Class *cl, OOP_Object *o, ohci_td_t *td);
364 void ohci_FreeED(OOP_Class *cl, OOP_Object *o, ohci_ed_t *ed);
366 void ohci_Delay(struct timerequest *tr, uint32_t msec);
367 struct timerequest *ohci_CreateTimer();
368 void ohci_DeleteTimer(struct timerequest *tr);
370 #endif /*OHCI_H_*/