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.
21 #include <aros/symbolsets.h>
23 #include <exec/types.h>
26 #include <dos/dosextens.h>
28 #include <hidd/hidd.h>
31 #include <devices/timer.h>
35 #include <proto/exec.h>
36 #include <proto/oop.h>
37 #include <proto/dos.h>
38 #include <aros/debug.h>
41 #include LC_LIBDEFS_FILE
43 OOP_AttrBase HiddUSBAttrBase
;
44 OOP_AttrBase HiddUSBDeviceAttrBase
;
45 OOP_AttrBase HiddUSBHubAttrBase
;
46 OOP_AttrBase HiddUSBDrvAttrBase
;
47 OOP_AttrBase HiddAttrBase
;
51 static void USB_ProcessStarter(struct usb_staticdata
*sd
, struct Task
*parent
)
53 struct Library
*DOSBase
;
54 struct MsgPort
*msgPort
= CreateMsgPort();
55 struct timerequest
*tr
= CreateIORequest(msgPort
, sizeof(struct timerequest
));
57 OpenDevice("timer.device", UNIT_VBLANK
, (struct IORequest
*)tr
, 0);
59 D(bug("[USB] Process starter\n"));
61 while(!(DOSBase
= OpenLibrary("dos.library", 0)))
63 tr
->tr_time
.tv_usec
= 0;
64 tr
->tr_time
.tv_sec
= 2;
65 tr
->tr_node
.io_Command
= TR_ADDREQUEST
;
67 DoIO((struct IORequest
*)tr
);
70 D(bug("[USB] Process starter: dos.library up and running\n"));
71 D(bug("[USB] Process starter: Creating the main USB process\n"));
72 struct usbEvent message
;
74 struct TagItem tags
[] = {
75 { NP_Entry
, (IPTR
)usb_process
},
76 { NP_UserData
, (IPTR
)sd
},
78 { NP_Name
, (IPTR
)"USB" },
83 message
.ev_Message
.mn_ReplyPort
= CreateMsgPort();
84 message
.ev_Type
= evt_Startup
;
86 sd
->usbProcess
= CreateNewProc(tags
);
87 PutMsg(&sd
->usbProcess
->pr_MsgPort
, (struct Message
*)&message
);
88 WaitPort(message
.ev_Message
.mn_ReplyPort
);
89 DeleteMsgPort(message
.ev_Message
.mn_ReplyPort
);
91 CloseLibrary(DOSBase
);
92 CloseDevice((struct IORequest
*)tr
);
94 DeleteMsgPort(msgPort
);
97 Signal(parent
, SIGF_SINGLE
);
100 static int USB_Init(LIBBASETYPEPTR LIBBASE
)
102 struct OOP_ABDescr attrbases
[] = {
103 { (STRPTR
)IID_Hidd
, &HiddAttrBase
},
104 { (STRPTR
)IID_Hidd_USB
, &HiddUSBAttrBase
},
105 { (STRPTR
)IID_Hidd_USBDevice
, &HiddUSBDeviceAttrBase
},
106 { (STRPTR
)IID_Hidd_USBHub
, &HiddUSBHubAttrBase
},
107 { (STRPTR
)IID_Hidd_USBDrv
, &HiddUSBDrvAttrBase
},
111 D(bug("[USB] USB Init\n"));
113 NEWLIST(&LIBBASE
->sd
.driverList
);
114 NEWLIST(&LIBBASE
->sd
.extClassList
);
115 InitSemaphore(&LIBBASE
->sd
.global_lock
);
116 InitSemaphore(&LIBBASE
->sd
.driverListLock
);
118 if (OOP_ObtainAttrBases(attrbases
))
120 LIBBASE
->sd
.usb
= OOP_NewObject(NULL
, CLID_Hidd_USB
, NULL
);
122 if ((LIBBASE
->sd
.MemPool
= CreatePool(MEMF_PUBLIC
|MEMF_CLEAR
|MEMF_SEM_PROTECTED
, 8192, 4096)) != NULL
)
124 struct Library
*DOSBase
= OpenLibrary("dos.library", 0);
126 struct TagItem tags
[] = {
127 { TASKTAG_ARG1
, (IPTR
)&LIBBASE
->sd
},
128 { TASKTAG_ARG2
, 0UL },
132 tags
[1].ti_Data
= (IPTR
)FindTask(NULL
);
134 struct Task
*t
= AllocMem(sizeof(struct Task
), MEMF_PUBLIC
|MEMF_CLEAR
);
135 struct MemList
*ml
= AllocMem(sizeof(struct MemList
) + sizeof(struct MemEntry
), MEMF_PUBLIC
|MEMF_CLEAR
);
139 uint8_t *sp
= AllocMem(10240, MEMF_PUBLIC
|MEMF_CLEAR
);
140 uint8_t *name
= "USB Process starter";
143 t
->tc_SPUpper
= sp
+ 10240;
144 #if AROS_STACK_GROWS_DOWNWARDS
145 t
->tc_SPReg
= (char *)t
->tc_SPUpper
- SP_OFFSET
;
147 t
->tc_SPReg
= (char *)t
->tc_SPLower
+ SP_OFFSET
;
150 ml
->ml_NumEntries
= 2;
151 ml
->ml_ME
[0].me_Addr
= t
;
152 ml
->ml_ME
[0].me_Length
= sizeof(struct Task
);
153 ml
->ml_ME
[1].me_Addr
= sp
;
154 ml
->ml_ME
[1].me_Length
= 10240;
156 NEWLIST(&t
->tc_MemEntry
);
157 ADDHEAD(&t
->tc_MemEntry
, &ml
->ml_Node
);
159 t
->tc_Node
.ln_Name
= name
;
160 t
->tc_Node
.ln_Type
= NT_TASK
;
161 t
->tc_Node
.ln_Pri
= 1; /* same priority as input.device */
163 /* Add task. It will get back in touch soon */
164 NewAddTask(t
, USB_ProcessStarter
, NULL
, &tags
[0]);
173 CloseLibrary(DOSBase
);
175 OOP_ReleaseAttrBases(attrbases
);
181 static int USB_Expunge(LIBBASETYPEPTR LIBBASE
)
183 struct OOP_ABDescr attrbases
[] = {
184 { (STRPTR
)IID_Hidd
, &HiddAttrBase
},
185 { (STRPTR
)IID_Hidd_USB
, &HiddUSBAttrBase
},
186 { (STRPTR
)IID_Hidd_USBDevice
, &HiddUSBDeviceAttrBase
},
187 { (STRPTR
)IID_Hidd_USBHub
, &HiddUSBHubAttrBase
},
188 { (STRPTR
)IID_Hidd_USBDrv
, &HiddUSBDrvAttrBase
},
191 struct usbEvent message
;
193 D(bug("[USB] USB Expunge\n"));
195 message
.ev_Message
.mn_ReplyPort
= CreateMsgPort();
196 message
.ev_Type
= evt_Cleanup
;
198 PutMsg(&LIBBASE
->sd
.usbProcess
->pr_MsgPort
, (struct Message
*)&message
);
199 WaitPort(message
.ev_Message
.mn_ReplyPort
);
200 DeleteMsgPort(message
.ev_Message
.mn_ReplyPort
);
202 OOP_ReleaseAttrBases(attrbases
);
204 DeletePool(LIBBASE
->sd
.MemPool
);
209 ADD2INITLIB(USB_Init
, 0)
210 ADD2EXPUNGELIB(USB_Expunge
, 0)