grub2: bring back build of aros-side grub2 tools
[AROS.git] / workbench / devs / USB / stack / usbprocess.c
blob1eb5b5850b44feed7814dd2cc2da4fa65f5d46b5
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 #define DEBUG 0
23 #include <aros/debug.h>
25 #include <exec/types.h>
26 #include <oop/oop.h>
27 #include <dos/dos.h>
28 #include <dos/dosextens.h>
29 #include <devices/timer.h>
31 #include <hidd/hidd.h>
32 #include <usb/usb.h>
33 #include <usb/usb_core.h>
35 #include <proto/oop.h>
36 #include <proto/dos.h>
38 #include <string.h>
39 #include <stdio.h>
41 #include "usb.h"
44 * Alloc a unique 7-bit address for a device
46 uint8_t allocBitmap(uint32_t *bmp)
48 uint8_t addr;
50 for (addr = 0; addr < BITMAP_SIZE; addr++)
52 int byte = addr / 32;
53 int bit = 31 - (addr % 32);
55 if (!(bmp[byte] & (1 << bit))) {
56 bmp[byte] |= 1 << bit;
57 break;
61 if (addr == BITMAP_SIZE)
62 addr = 0xff;
64 return addr;
68 * Make a 7-bit address free for use
70 void freeBitmap(uint32_t *bmp, uint8_t addr)
72 uint8_t byte = addr / 32;
73 uint8_t bit = 31 - (addr % 32);
75 if (addr < BITMAP_SIZE)
77 bmp[byte] &= ~(1 << bit);
82 * AllocAbs the specified address
84 void setBitmap(uint32_t *bmp, uint8_t addr)
86 uint8_t byte = addr / 32;
87 uint8_t bit = 31 - (addr % 32);
89 if (addr < BITMAP_SIZE)
91 bmp[byte] |= 1 << bit;
95 static void ScanDirectory(struct Library *DOSBase, struct usb_staticdata *sd, STRPTR dir)
97 struct AnchorPath ap;
98 uint8_t match[2048];
99 int32_t err;
101 snprintf(match, sizeof(match)-1, "%s/#?.hidd", dir);
103 D(bug("[USB] match = \"%s\"\n", match));
105 memset(&ap, 0, sizeof(ap));
107 err = MatchFirst(match, &ap);
108 while ((err == 0))
110 if (ap.ap_Info.fib_EntryType < 0)
112 struct usb_ExtClass *ec = NULL;
113 int found = 0;
115 snprintf(match, sizeof(match)-1, "%s/%s", dir, ap.ap_Info.fib_FileName);
117 ForeachNode(&sd->extClassList, ec)
119 if (!strcmp(ap.ap_Info.fib_FileName, ec->ec_ShortName))
121 found = 1;
122 break;
126 if (!found)
129 ec = AllocVecPooled(sd->MemPool, sizeof(struct usb_ExtClass));
131 D(bug("[USB] external class \"%s\" not yet in the list. Adding it\n", match));
133 if (ec)
135 // ec->ec_LibBase = OpenLibrary(match, 0);
136 // if (!ec->ec_LibBase)
137 // {
138 // FreeVecPooled(sd->MemPool, ec);
139 // }
140 // else
142 ec->ec_Node.ln_Name = AllocVecPooled(sd->MemPool, strlen(match)+1);
143 CopyMem(match, ec->ec_Node.ln_Name, strlen(match)+1);
144 ec->ec_ShortName = AllocVecPooled(sd->MemPool, strlen(ap.ap_Info.fib_FileName)+1);
145 CopyMem(ap.ap_Info.fib_FileName, (char *)ec->ec_ShortName, strlen(ap.ap_Info.fib_FileName)+1);
146 AddTail(&sd->extClassList, &ec->ec_Node);
151 err = MatchNext(&ap);
153 MatchEnd(&ap);
156 void UpdatePaths(struct Library *DOSBase, struct usb_staticdata *sd)
158 struct DosList *dl = LockDosList(LDF_READ | LDF_ASSIGNS);
160 if (dl)
162 if ((dl = FindDosEntry(dl, "USBCLASSES", LDF_ASSIGNS)) != NULL)
164 struct AssignList *nextAssign;
165 uint8_t dirName[2048];
167 if (NameFromLock(dl->dol_Lock, dirName, sizeof(dirName)))
169 D(bug("[USB] Scanning '%s'\n", dirName));
171 ScanDirectory(DOSBase, sd, dirName);
174 nextAssign = dl->dol_misc.dol_assign.dol_List;
175 while (nextAssign != NULL)
177 if (NameFromLock(nextAssign->al_Lock, dirName, sizeof(dirName)))
179 D(bug("[USB] Scanning '%s'\n", dirName));
181 ScanDirectory(DOSBase, sd, dirName);
184 nextAssign = nextAssign->al_Next;
188 UnLockDosList(LDF_READ | LDF_ASSIGNS);
192 static void CleanupProcess()
196 void usb_process()
198 struct usb_staticdata *sd = (struct usb_staticdata *)(FindTask(NULL)->tc_UserData);
199 struct Process *usbProcess = (struct Process *)FindTask(NULL);
200 struct usbEvent *ev = NULL;
201 struct MsgPort *port;
202 struct timerequest *tr;
204 struct Library *DOSBase = OpenLibrary("dos.library", 0);
206 port = CreateMsgPort();
207 tr = CreateIORequest(port, sizeof(struct timerequest));
208 OpenDevice("timer.device", UNIT_VBLANK, (struct IORequest *)tr, 0);
210 tr->tr_node.io_Command = TR_ADDREQUEST;
211 tr->tr_time.tv_sec = 10;
212 tr->tr_time.tv_usec = 0;
213 SendIO((struct IORequest *)tr);
215 D(bug("[USB Process] Hello. Task @ %p, signals = %08x\n", FindTask(NULL), FindTask(NULL)->tc_SigAlloc));
217 UpdatePaths(DOSBase, sd);
219 for(;;)
221 Wait((1 << usbProcess->pr_MsgPort.mp_SigBit) |
222 (1 << port->mp_SigBit));
224 if (GetMsg(port))
226 UpdatePaths(DOSBase, sd);
228 tr->tr_node.io_Command = TR_ADDREQUEST;
229 tr->tr_time.tv_sec = 10;
230 tr->tr_time.tv_usec = 0;
231 SendIO((struct IORequest *)tr);
234 while ((ev = (struct usbEvent *)GetMsg(&usbProcess->pr_MsgPort)) != NULL)
236 switch (ev->ev_Type)
238 case evt_Startup:
239 D(bug("[USB Process] Startup MSG\n"));
240 ReplyMsg(&ev->ev_Message);
241 break;
243 case evt_Method:
244 D(bug("[USB Process] Sync method call\n"));
245 ev->ev_RetVal = OOP_DoMethod(ev->ev_Target, (OOP_Msg)&ev->ev_Event);
246 ReplyMsg(&ev->ev_Message);
247 break;
249 case evt_AsyncMethod:
250 D(bug("[USB Process] Async method call\n"));
251 OOP_DoMethod(ev->ev_Target, (OOP_Msg)&ev->ev_Event);
252 FreeVecPooled(sd->MemPool, ev);
253 break;
255 case evt_Cleanup:
256 D(bug("[USB Process] Cleanup MSG\n"));
257 CleanupProcess();
258 ReplyMsg(&ev->ev_Message);
259 CloseLibrary(DOSBase);
260 return;
262 default:
263 break;