1 /* dev.c - pciuhci.device based on work by Chris Hodges */
5 #include <proto/exec.h>
6 #include <proto/utility.h>
10 static int devInit(LIBBASETYPEPTR base
) {
11 KPRINTF(10, ("devInit base: 0x%p SysBase: 0x%p\n", base
, SysBase
));
13 base
->hd_MemPool
= CreatePool(MEMF_PUBLIC
| MEMF_CLEAR
| MEMF_SEM_PROTECTED
, 16384, 4096);
14 if(base
->hd_MemPool
) {
15 NEWLIST(&base
->hd_Units
);
16 KPRINTF(10, ("devInit: Ok\n"));
18 KPRINTF(10, ("devInit: CreatePool() failed!\n"));
22 KPRINTF(10, ("devInit: openCnt = %ld\n", base
->hd_Library
.lib_OpenCnt
));
27 *===========================================================
28 * devOpen(ioreq, unit, flags, base)
29 *===========================================================
31 * This is the the DEV_OPEN function.
34 static int devOpen(LIBBASETYPEPTR base
, struct IOUsbHWReq
*ioreq
, ULONG unit
, ULONG flags
) {
35 KPRINTF(10, ("devOpen ioreq: 0x%p unit: %ld flags: 0x%08lx base: 0x%p\n",
36 ioreq
, unit
, flags
, base
));
38 KPRINTF(10, ("devOpen: openCnt = %ld\n", base
->hd_Library
.lib_OpenCnt
));
40 if(ioreq
->iouh_Req
.io_Message
.mn_Length
< sizeof(struct IOUsbHWReq
)) {
41 KPRINTF(20, ("devOpen: invalid MN_LENGTH!\n"));
43 ioreq
->iouh_Req
.io_Error
= IOERR_BADLENGTH
;
45 /* Default to open failure. */
46 ioreq
->iouh_Req
.io_Error
= IOERR_OPENFAIL
;
48 ioreq
->iouh_Req
.io_Unit
= Open_Unit(ioreq
, unit
, base
);
49 if(!ioreq
->iouh_Req
.io_Unit
)
51 KPRINTF(20, ("devOpen: could not open unit!\n"));
54 ioreq
->iouh_Req
.io_Message
.mn_Node
.ln_Type
= NT_REPLYMSG
;
55 ioreq
->iouh_Req
.io_Error
= 0;
66 *===========================================================
67 * devClose(ioreq, base)
68 *===========================================================
70 * This is the the DEV_EXPUNGE function.
74 static int devClose(LIBBASETYPEPTR base
, struct IOUsbHWReq
*ioreq
) {
75 KPRINTF(10, ("devClose ioreq: 0x%p base: 0x%p\n", ioreq
, base
));
77 Close_Unit(base
, (struct PCIUnit
*) ioreq
->iouh_Req
.io_Unit
, ioreq
);
79 ioreq
->iouh_Req
.io_Unit
= (APTR
) -1;
80 ioreq
->iouh_Req
.io_Device
= (APTR
) -1;
85 static int devExpunge(LIBBASETYPEPTR base
) {
88 DeletePool(base
->hd_MemPool
);
93 ADD2INITLIB(devInit
, 0)
94 ADD2OPENDEV(devOpen
, 0)
95 ADD2CLOSEDEV(devClose
, 0)
96 ADD2EXPUNGELIB(devExpunge
, 0)
99 *===========================================================
100 * devBeginIO(ioreq, base)
101 *===========================================================
103 * This is the DEV_BEGINIO vector of the device.
106 AROS_LH1(void, devBeginIO
,
107 AROS_LHA(struct IOUsbHWReq
*, ioreq
, A1
),
108 LIBBASETYPEPTR
, base
, 5, pciuhci
)
112 struct PCIUnit
*unit
= (struct PCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
115 //KPRINTF(1, ("devBeginIO ioreq: 0x%08lx base: 0x%08lx cmd: %lu\n", ioreq, base, ioreq->iouh_Req.io_Command));
117 ioreq
->iouh_Req
.io_Message
.mn_Node
.ln_Type
= NT_MESSAGE
;
118 ioreq
->iouh_Req
.io_Error
= UHIOERR_NO_ERROR
;
120 if (ioreq
->iouh_Req
.io_Command
< NSCMD_DEVICEQUERY
) {
121 switch (ioreq
->iouh_Req
.io_Command
) {
123 ret
= cmdReset(ioreq
, unit
, base
);
127 ret
= cmdFlush(ioreq
, unit
, base
);
130 case UHCMD_QUERYDEVICE
:
131 ret
= cmdQueryDevice(ioreq
, unit
, base
);
135 ret
= cmdUsbReset(ioreq
, unit
, base
);
138 case UHCMD_USBRESUME
:
139 ret
= cmdUsbResume(ioreq
, unit
, base
);
142 case UHCMD_USBSUSPEND
:
143 ret
= cmdUsbSuspend(ioreq
, unit
, base
);
147 ret
= cmdUsbOper(ioreq
, unit
, base
);
150 case UHCMD_CONTROLXFER
:
151 ret
= cmdControlXFer(ioreq
, unit
, base
);
155 ret
= cmdBulkXFer(ioreq
, unit
, base
);
159 ret
= cmdIntXFer(ioreq
, unit
, base
);
163 ret
= cmdIsoXFer(ioreq
, unit
, base
);
171 switch(ioreq
->iouh_Req
.io_Command
) {
172 case NSCMD_DEVICEQUERY
:
173 KPRINTF2(200,("cmdNSDeviceQuery\n"));
175 static const UWORD NSDSupported
[] = {
176 CMD_FLUSH
, CMD_RESET
,
190 struct NSDeviceQueryResult
*nsdq
= (struct NSDeviceQueryResult
*)((struct IOStdReq
*)(ioreq
))->io_Data
;
191 nsdq
->DevQueryFormat
= 0;
192 nsdq
->SizeAvailable
= sizeof(struct NSDeviceQueryResult
);
193 nsdq
->DeviceType
= NSDEVTYPE_USBHARDWARE
;
194 nsdq
->DeviceSubType
= 0;
195 nsdq
->SupportedCommands
= (UWORD
*)NSDSupported
;
207 if(ret
!= RC_DONTREPLY
) {
208 /* Set error codes */
210 ioreq
->iouh_Req
.io_Error
= ret
& 0xff;
212 /* Terminate the iorequest */
213 ioreq
->iouh_Req
.io_Message
.mn_Node
.ln_Type
= NT_FREEMSG
;
214 /* If not quick I/O, reply the message */
215 if(!(ioreq
->iouh_Req
.io_Flags
& IOF_QUICK
)) {
216 ReplyMsg(&ioreq
->iouh_Req
.io_Message
);
224 *===========================================================
225 * devAbortIO(ioreq, base)
226 *===========================================================
228 * This is the DEV_ABORTIO vector of the device. It abort
229 * the given iorequest, and set
232 AROS_LH1(LONG
, devAbortIO
,
233 AROS_LHA(struct IOUsbHWReq
*, ioreq
, A1
),
234 LIBBASETYPEPTR
, base
, 6, pciuhci
)
238 KPRINTF(50, ("devAbortIO ioreq: 0x%p, command %ld, status %ld\n", ioreq
, ioreq
->iouh_Req
.io_Command
, ioreq
->iouh_Req
.io_Message
.mn_Node
.ln_Type
));
241 if(ioreq
->iouh_Req
.io_Message
.mn_Node
.ln_Type
== NT_MESSAGE
) {
242 if(cmdAbortIO(ioreq
, base
)) {