2 Copyright (C) 2006 by Michal Schulz
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.
23 #include <aros/debug.h>
25 #include <exec/types.h>
28 #include <dos/dosextens.h>
29 #include <devices/timer.h>
31 #include <hidd/hidd.h>
33 #include <usb/usb_core.h>
35 #include <proto/oop.h>
36 #include <proto/dos.h>
44 * Alloc a unique 7-bit address for a device
46 uint8_t allocBitmap(uint32_t *bmp
)
50 for (addr
= 0; addr
< BITMAP_SIZE
; addr
++)
53 int bit
= 31 - (addr
% 32);
55 if (!(bmp
[byte
] & (1 << bit
))) {
56 bmp
[byte
] |= 1 << bit
;
61 if (addr
== BITMAP_SIZE
)
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
)
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
);
110 if (ap
.ap_Info
.fib_EntryType
< 0)
112 struct usb_ExtClass
*ec
= NULL
;
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
))
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
));
135 // ec->ec_LibBase = OpenLibrary(match, 0);
136 // if (!ec->ec_LibBase)
138 // FreeVecPooled(sd->MemPool, ec);
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
);
156 void UpdatePaths(struct Library
*DOSBase
, struct usb_staticdata
*sd
)
158 struct DosList
*dl
= LockDosList(LDF_READ
| LDF_ASSIGNS
);
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()
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
);
221 Wait((1 << usbProcess
->pr_MsgPort
.mp_SigBit
) |
222 (1 << port
->mp_SigBit
));
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
)
239 D(bug("[USB Process] Startup MSG\n"));
240 ReplyMsg(&ev
->ev_Message
);
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
);
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
);
256 D(bug("[USB Process] Cleanup MSG\n"));
258 ReplyMsg(&ev
->ev_Message
);
259 CloseLibrary(DOSBase
);