Fixed compatibility of output.
[AROS.git] / workbench / devs / USB / drivers / OHCI / ohci_init.c
blob5b2de5e72f09092e04b04e736411142201a0c623
1 /*
2 Copyright (C) 2006 by Michal Schulz
3 $Id$
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with this program; if not, write to the
17 Free Software Foundation, Inc.,
18 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 #include <inttypes.h>
22 #include <aros/symbolsets.h>
24 #include <asm/io.h>
26 #include <hidd/hidd.h>
27 #include <hidd/pci.h>
29 #include <usb/usb.h>
31 #define DEBUG 1
33 #include <proto/exec.h>
34 #include <proto/oop.h>
35 #include <aros/debug.h>
37 #include "ohci.h"
39 #undef SD
40 #define SD(x) (&LIBBASE->sd)
42 static
43 AROS_UFH3(void, Enumerator,
44 AROS_UFHA(struct Hook *, hook, A0),
45 AROS_UFHA(OOP_Object *, pciDevice, A2),
46 AROS_UFHA(APTR, message, A1))
48 AROS_USERFUNC_INIT
50 ohci_registers_t *regs;
51 static int counter;
52 struct timerequest *tr = ohci_CreateTimer();
53 intptr_t tmp;
55 if (counter == MAX_OHCI_DEVICES)
56 return;
58 LIBBASETYPE *LIBBASE = (LIBBASETYPE *)hook->h_Data;
60 struct TagItem attrs[] = {
61 { aHidd_PCIDevice_isMEM, TRUE },
62 { aHidd_PCIDevice_isMaster, TRUE },
63 { TAG_DONE, 0UL },
66 OOP_SetAttrs(pciDevice, (struct TagItem *)attrs);
67 OOP_GetAttr(pciDevice, aHidd_PCIDevice_Base0, &LIBBASE->sd.ramBase[counter]);
68 OOP_GetAttr(pciDevice, aHidd_PCIDevice_Driver, (void *)&LIBBASE->sd.pciDriver[counter]);
69 OOP_GetAttr(pciDevice, aHidd_PCIDevice_INTLine, &tmp);
71 LIBBASE->sd.irqNum[counter] = tmp;
72 LIBBASE->sd.pciDevice[counter] = pciDevice;
74 regs = (ohci_registers_t *)LIBBASE->sd.ramBase[counter];
76 LIBBASE->sd.numPorts[counter] = HC_RHA_GET_NDP(AROS_OHCI2LONG(mmio(regs->HcRhDescriptorA)));
78 D(bug("[OHCI] %d-port Device %d @ %08x with MMIO @ %08x\n", LIBBASE->sd.numPorts[counter], counter + 1, pciDevice, LIBBASE->sd.ramBase[counter]));
80 uint32_t ctrl = AROS_OHCI2LONG(mmio(regs->HcControl));
81 if (ctrl & HC_CTRL_IR)
83 D(bug("[OHCI] Performing BIOS handoff\n"));
84 int delay = 500; /* 0.5 second */
85 mmio(regs->HcInterruptEnable) = AROS_LONG2OHCI(HC_INTR_OC);
86 mmio(regs->HcCommandStatus) = AROS_LONG2OHCI(HC_CS_OCR);
88 /* Loop */
89 while ((delay > 0) && AROS_OHCI2LONG(mmio(regs->HcControl) & HC_CTRL_IR))
91 delay -= 2;
92 ohci_Delay(tr, 2);
94 if (delay < 0)
95 D(bug("[OHCI] BIOS handoff failed!\n"));
97 mmio(regs->HcControl) = AROS_LONG2OHCI(ctrl & HC_CTRL_RWC);
100 /* Disable all interrupts */
101 mmio(regs->HcInterruptDisable) = AROS_LONG2OHCI(0xffffffff);
102 mmio(regs->HcInterruptStatus) = AROS_LONG2OHCI(0xffffffff);
104 LIBBASE->sd.numDevices = ++counter;
106 ohci_DeleteTimer(tr);
108 AROS_USERFUNC_EXIT
112 static int OHCI_Init(LIBBASETYPEPTR LIBBASE)
114 D(bug("[OHCI] OHCI_Init()\n"));
116 LIBBASE->sd.usb = OOP_NewObject(NULL, (STRPTR)CLID_Hidd_USB, NULL);
118 NEWLIST(&LIBBASE->sd.tdList);
119 InitSemaphore(&LIBBASE->sd.tdLock);
121 if (!LIBBASE->sd.usb)
123 bug("[OHCI] Cannot create the instance of base USB class\n");
124 return FALSE;
127 if ((LIBBASE->sd.pci=OOP_NewObject(NULL, (STRPTR)CLID_Hidd_PCI, NULL)))
129 struct TagItem tags[] = {
130 { tHidd_PCI_Class, PCI_BASE_CLASS_SERIAL },
131 { tHidd_PCI_SubClass, PCI_SUB_CLASS_USB },
132 { tHidd_PCI_Interface, PCI_INTERFACE_OHCI },
133 { TAG_DONE, 0UL }
136 struct OOP_ABDescr attrbases[] = {
137 { (STRPTR)IID_Hidd, &HiddAttrBase },
138 { (STRPTR)IID_Hidd_PCIDevice, &HiddPCIDeviceAttrBase },
139 { (STRPTR)IID_Hidd_USBDevice, &HiddUSBDeviceAttrBase },
140 { (STRPTR)IID_Hidd_USBHub, &HiddUSBHubAttrBase },
141 { (STRPTR)IID_Hidd_USBDrv, &HiddUSBDrvAttrBase },
142 { NULL, NULL }
145 struct Hook FindHook = {
146 h_Entry: (IPTR (*)())Enumerator,
147 h_Data: LIBBASE,
150 OOP_ObtainAttrBases(attrbases);
152 D(bug("[OHCI] Searching for OHCI devices...\n"));
154 HIDD_PCI_EnumDevices(LIBBASE->sd.pci, &FindHook, (struct TagItem *)&tags);
156 D(bug("[OHCI] Done. OHCI devices found: %d\n", LIBBASE->sd.numDevices));
158 if (LIBBASE->sd.numDevices > 0)
160 LIBBASE->sd.memPool = CreatePool(MEMF_CLEAR | MEMF_PUBLIC | MEMF_SEM_PROTECTED, 8192, 4096);
162 if (LIBBASE->sd.memPool)
163 return TRUE;
168 return FALSE;
171 static int OHCI_Expunge(LIBBASETYPEPTR LIBBASE)
173 struct OOP_ABDescr attrbases[] = {
174 { (STRPTR)IID_Hidd, &HiddAttrBase },
175 { (STRPTR)IID_Hidd_PCIDevice, &HiddPCIDeviceAttrBase },
176 { (STRPTR)IID_Hidd_USBDevice, &HiddUSBDeviceAttrBase },
177 { (STRPTR)IID_Hidd_USBHub, &HiddUSBHubAttrBase },
178 { (STRPTR)IID_Hidd_USBDrv, &HiddUSBDrvAttrBase },
179 { NULL, NULL }
182 OOP_ReleaseAttrBases(attrbases);
184 return TRUE;
187 ADD2INITLIB(OHCI_Init, 0)
188 ADD2EXPUNGELIB(OHCI_Expunge, 0)
189 ADD2LIBS((STRPTR)"usb.hidd", 0, static struct Library *, __usbbase)