grub2: bring back build of aros-side grub2 tools
[AROS.git] / workbench / devs / USB / drivers / UHCI / uhci_init.c
blob409cc3e6cf3db4a7754c2d788ff3efd3130babdf
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 <aros/symbolsets.h>
23 #include <exec/types.h>
24 #include <oop/oop.h>
26 #include <asm/io.h>
28 #include <hidd/hidd.h>
29 #include <hidd/pci.h>
31 #include <usb/usb.h>
33 #define DEBUG 0
35 #include <proto/exec.h>
36 #include <proto/oop.h>
37 #include <aros/debug.h>
39 #include "uhci.h"
41 #undef SD
42 #define SD(x) (&LIBBASE->sd)
45 * usb_delay() stops waits for specified amount of miliseconds. It uses the timerequest
46 * of specified USB device. No pre-allocation of signals is required.
48 static void USBDelay(struct timerequest *tr, uint32_t msec)
50 /* Allocate a signal within this task context */
51 tr->tr_node.io_Message.mn_ReplyPort->mp_SigBit = AllocSignal(-1);
52 tr->tr_node.io_Message.mn_ReplyPort->mp_SigTask = FindTask(NULL);
54 /* Specify the request */
55 tr->tr_node.io_Command = TR_ADDREQUEST;
56 tr->tr_time.tv_secs = msec / 1000;
57 tr->tr_time.tv_micro = 1000 * (msec % 1000);
59 /* Wait */
60 DoIO((struct IORequest *)tr);
62 /* The signal is not needed anymore */
63 FreeSignal(tr->tr_node.io_Message.mn_ReplyPort->mp_SigBit);
64 tr->tr_node.io_Message.mn_ReplyPort->mp_SigTask = NULL;
68 static struct timerequest *USBCreateTimer()
70 struct timerequest *tr = NULL;
71 struct MsgPort *mp = NULL;
73 mp = CreateMsgPort();
74 if (mp)
76 tr = (struct timerequest *)CreateIORequest(mp, sizeof(struct timerequest));
77 if (tr)
79 FreeSignal(mp->mp_SigBit);
80 if (!OpenDevice((STRPTR)"timer.device", UNIT_MICROHZ, (struct IORequest *)tr, 0))
81 return tr;
83 DeleteIORequest((struct IORequest *)tr);
84 mp->mp_SigBit = AllocSignal(-1);
86 DeleteMsgPort(mp);
89 return NULL;
92 static void USBDeleteTimer(struct timerequest *tr)
94 if (tr)
96 tr->tr_node.io_Message.mn_ReplyPort->mp_SigBit = AllocSignal(-1);
97 CloseDevice((struct IORequest *)tr);
98 DeleteMsgPort(tr->tr_node.io_Message.mn_ReplyPort);
99 DeleteIORequest((struct IORequest *)tr);
103 static
104 AROS_UFH3(void, Enumerator,
105 AROS_UFHA(struct Hook *, hook, A0),
106 AROS_UFHA(OOP_Object *, pciDevice, A2),
107 AROS_UFHA(APTR, message, A1))
109 AROS_USERFUNC_INIT
111 static int counter;
113 if (counter == MAX_DEVS)
114 return;
116 LIBBASETYPE *LIBBASE = (LIBBASETYPE *)hook->h_Data;
118 struct TagItem attrs[] = {
119 { aHidd_PCIDevice_isIO, TRUE },
120 { aHidd_PCIDevice_isMaster, TRUE },
121 { TAG_DONE, 0UL },
124 OOP_SetAttrs(pciDevice, (struct TagItem *)attrs);
125 OOP_GetAttr(pciDevice, aHidd_PCIDevice_Base4, &LIBBASE->sd.iobase[counter]);
126 OOP_GetAttr(pciDevice, aHidd_PCIDevice_Driver, (APTR)&LIBBASE->sd.uhciPCIDriver[counter]);
127 LIBBASE->sd.uhciDevice[counter] = pciDevice;
129 D(bug("[UHCI] Device %d @ %08x with IO @ %08x\n", counter, pciDevice, LIBBASE->sd.iobase[counter]));
131 D(bug("[UHCI] Performing full reset. Hopefull legacy USB will do it'S handoff at this time.\n"));
132 HIDD_PCIDevice_WriteConfigWord(pciDevice, PCI_LEGSUP, 0x8f00);
134 outw(UHCI_CMD_HCRESET, LIBBASE->sd.iobase[counter] + UHCI_CMD);
135 struct timerequest *tr = USBCreateTimer();
136 USBDelay(tr, 10);
137 USBDeleteTimer(tr);
138 if (inw((uint16_t *)(LIBBASE->sd.iobase[counter] + UHCI_CMD)) & UHCI_CMD_HCRESET)
139 D(bug("[UHCI] Wrrr. Reset not yet completed\n"));
141 outw(0, LIBBASE->sd.iobase[counter] + UHCI_INTR);
142 outw(0, LIBBASE->sd.iobase[counter] + UHCI_CMD);
145 D(bug("[UHCI] 0xc0: %04x\n", HIDD_PCIDevice_ReadConfigWord(pciDevice, 0xc0)));
147 LIBBASE->sd.num_devices = ++counter;
149 AROS_USERFUNC_EXIT
152 static int UHCI_Init(LIBBASETYPEPTR LIBBASE)
154 D(bug("[UHCI] UHCI_Init()\n"));
156 LIBBASE->sd.usb = OOP_NewObject(NULL, (STRPTR)CLID_Hidd_USB, NULL);
158 if (!LIBBASE->sd.usb)
160 bug("[UHCI] Cannot create the instance of base USB class\n");
161 return FALSE;
164 if ((LIBBASE->sd.pci=OOP_NewObject(NULL, (STRPTR)IID_Hidd_PCI, NULL)))
166 struct TagItem tags[] = {
167 { tHidd_PCI_Class, PCI_BASE_CLASS_SERIAL },
168 { tHidd_PCI_SubClass, PCI_SUB_CLASS_USB },
169 { tHidd_PCI_Interface, PCI_INTERFACE_UHCI },
170 { TAG_DONE, 0UL }
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 struct Hook FindHook = {
183 h_Entry: (IPTR (*)())Enumerator,
184 h_Data: LIBBASE,
187 NEWLIST(&LIBBASE->sd.td_list);
188 InitSemaphore(&LIBBASE->sd.global_lock);
190 OOP_ObtainAttrBases(attrbases);
192 D(bug("[UHCI] Searching for UHCI devices...\n"));
194 HIDD_PCI_EnumDevices(LIBBASE->sd.pci, &FindHook, (struct TagItem *)&tags);
196 D(bug("[UHCI] Done. UHCI devices found: %d\n", LIBBASE->sd.num_devices));
198 if (LIBBASE->sd.num_devices > 0)
200 LIBBASE->sd.MemPool = CreatePool(MEMF_CLEAR | MEMF_PUBLIC | MEMF_SEM_PROTECTED, 8192, 4096);
202 if (LIBBASE->sd.MemPool)
203 return TRUE;
207 return FALSE;
210 static int UHCI_Expunge(LIBBASETYPEPTR LIBBASE)
212 struct OOP_ABDescr attrbases[] = {
213 { (STRPTR)IID_Hidd, &HiddAttrBase },
214 { (STRPTR)IID_Hidd_PCIDevice, &HiddPCIDeviceAttrBase },
215 { (STRPTR)IID_Hidd_USBDevice, &HiddUSBDeviceAttrBase },
216 { (STRPTR)IID_Hidd_USBHub, &HiddUSBHubAttrBase },
217 { (STRPTR)IID_Hidd_USBDrv, &HiddUSBDrvAttrBase },
218 { NULL, NULL }
221 OOP_ReleaseAttrBases(attrbases);
223 return TRUE;
226 ADD2INITLIB(UHCI_Init, 0)
227 ADD2EXPUNGELIB(UHCI_Expunge, 0)
228 ADD2LIBS((STRPTR)"usb.hidd", 0, static struct Library *, __usbbase)