Split off OHCI support into a separate device. Numerous bug fixes, most
[AROS.git] / rom / usb / pciusbhc / ohci / dev.c
blob968d3c7cf7676ee76cb0cac80171ffdc0d44e893
1 /*
2 Copyright © 2002-2009, Chris Hodges. All rights reserved.
3 Copyright © 2010-2012, The AROS Development Team. All rights reserved.
4 $Id$
5 */
7 #include <proto/exec.h>
8 #include <proto/utility.h>
9 #include <clib/alib_protos.h>
11 #include "debug.h"
13 #include "cmd_protos.h"
14 #include "pci_protos.h"
16 #define UtilityBase base->hd_UtilityBase
18 const char devname[] = MOD_NAME_STRING;
19 CONST_STRPTR xfer_names[] = {"CONTROL", "BULK", "ISO", "INT"};
21 static int devInit(LIBBASETYPEPTR base)
23 KPRINTF(10, ("devInit base: 0x%p SysBase: 0x%p\n", base, SysBase));
25 base->hd_UtilityBase = (APTR) OpenLibrary("utility.library", 39);
27 if (UtilityBase)
29 base->hd_MemPool =
30 CreatePool(MEMF_PUBLIC | MEMF_CLEAR | MEMF_SEM_PROTECTED, 16384,
31 4096);
32 if (base->hd_MemPool)
34 NewList(&base->hd_Units);
36 KPRINTF(10, ("devInit: Ok\n"));
38 else
40 KPRINTF(10, ("devInit: CreatePool() failed!\n"));
41 CloseLibrary((struct Library *)UtilityBase);
42 base = NULL;
45 else
47 KPRINTF(10,
48 ("devInit: OpenLibrary(\"utility.library\", 39) failed!\n"));
49 base = NULL;
52 KPRINTF(10, ("devInit: openCnt = %ld\n", base->hd_Library.lib_OpenCnt));
54 return base ? TRUE : FALSE;
58 *===========================================================
59 * devOpen(ioreq, unit, flags, base)
60 *===========================================================
62 * This is the the DEV_OPEN function.
65 static int devOpen(LIBBASETYPEPTR base, struct IOUsbHWReq *ioreq,
66 ULONG unit, ULONG flags)
68 KPRINTF(10,
69 ("devOpen ioreq: 0x%p unit: %ld flags: 0x%08lx base: 0x%p\n", ioreq,
70 unit, flags, base));
72 KPRINTF(10, ("devOpen: openCnt = %ld\n", base->hd_Library.lib_OpenCnt));
74 if (ioreq->iouh_Req.io_Message.mn_Length < sizeof(struct IOUsbHWReq))
76 KPRINTF(20, ("devOpen: invalid MN_LENGTH!\n"));
78 ioreq->iouh_Req.io_Error = IOERR_BADLENGTH;
80 else
82 /* Default to open failure. */
83 ioreq->iouh_Req.io_Error = IOERR_OPENFAIL;
85 ioreq->iouh_Req.io_Unit = Open_Unit(ioreq, unit, base);
86 if (!ioreq->iouh_Req.io_Unit)
88 KPRINTF(20, ("devOpen: could not open unit!\n"));
90 else
92 /* Opended ok! */
93 ioreq->iouh_Req.io_Message.mn_Node.ln_Type = NT_REPLYMSG;
94 ioreq->iouh_Req.io_Error = 0;
96 return TRUE;
100 return FALSE;
105 *===========================================================
106 * devClose(ioreq, base)
107 *===========================================================
109 * This is the the DEV_EXPUNGE function.
113 static int devClose(LIBBASETYPEPTR base, struct IOUsbHWReq *ioreq)
115 KPRINTF(10, ("devClose ioreq: 0x%p base: 0x%p\n", ioreq, base));
117 Close_Unit(base, (struct PCIUnit *)ioreq->iouh_Req.io_Unit, ioreq);
119 ioreq->iouh_Req.io_Unit = (APTR) - 1;
120 ioreq->iouh_Req.io_Device = (APTR) - 1;
121 return TRUE;
125 static int devExpunge(LIBBASETYPEPTR base)
127 pciExpunge(base);
129 DeletePool(base->hd_MemPool);
131 KPRINTF(5, ("devExpunge: closelibrary utilitybase 0x%p\n",
132 UtilityBase));
133 CloseLibrary((struct Library *)UtilityBase);
134 return TRUE;
137 ADD2INITLIB(devInit, 0)
138 ADD2OPENDEV(devOpen, 0)
139 ADD2CLOSEDEV(devClose, 0) ADD2EXPUNGELIB(devExpunge, 0)
141 *===========================================================
142 * devBeginIO(ioreq, base)
143 *===========================================================
145 * This is the DEV_BEGINIO vector of the device.
148 AROS_LH1(void, devBeginIO,
149 AROS_LHA(struct IOUsbHWReq *, ioreq, A1), LIBBASETYPEPTR, base, 5, ohci)
151 AROS_LIBFUNC_INIT
152 struct PCIUnit *unit = (struct PCIUnit *)ioreq->iouh_Req.io_Unit;
153 WORD ret;
155 ioreq->iouh_Req.io_Message.mn_Node.ln_Type = NT_MESSAGE;
156 ioreq->iouh_Req.io_Error = UHIOERR_NO_ERROR;
158 if (ioreq->iouh_Req.io_Command < NSCMD_DEVICEQUERY)
160 switch (ioreq->iouh_Req.io_Command)
162 case CMD_RESET:
163 ret = cmdReset(ioreq, unit, base);
164 break;
166 case CMD_FLUSH:
167 ret = cmdFlush(ioreq, unit, base);
168 break;
170 case UHCMD_QUERYDEVICE:
171 ret = cmdQueryDevice(ioreq, unit, base);
172 break;
174 case UHCMD_USBRESET:
175 ret = cmdUsbReset(ioreq, unit, base);
176 break;
178 case UHCMD_USBRESUME:
179 ret = cmdUsbResume(ioreq, unit, base);
180 break;
182 case UHCMD_USBSUSPEND:
183 ret = cmdUsbSuspend(ioreq, unit, base);
184 break;
186 case UHCMD_USBOPER:
187 ret = cmdUsbOper(ioreq, unit, base);
188 break;
190 case UHCMD_CONTROLXFER:
191 ret = cmdXFer(ioreq, unit, base);
192 break;
194 case UHCMD_BULKXFER:
195 ret = cmdXFer(ioreq, unit, base);
196 break;
198 case UHCMD_INTXFER:
199 ret = cmdXFer(ioreq, unit, base);
200 break;
202 case UHCMD_ISOXFER:
203 ret = cmdXFer(ioreq, unit, base);
204 break;
206 default:
207 ret = IOERR_NOCMD;
208 break;
211 else
213 switch (ioreq->iouh_Req.io_Command)
215 case NSCMD_DEVICEQUERY:
216 ret = cmdNSDeviceQuery((struct IOStdReq *)ioreq, unit, base);
217 break;
219 default:
220 ret = IOERR_NOCMD;
221 break;
225 if (ret != RC_DONTREPLY)
227 KPRINTF(1, ("TermIO\n"));
228 if (ret != RC_OK)
230 /* Set error codes */
231 ioreq->iouh_Req.io_Error = ret & 0xff;
233 /* Terminate the iorequest */
234 TermIO(ioreq, base);
237 AROS_LIBFUNC_EXIT}
240 *===========================================================
241 * devAbortIO(ioreq, base)
242 *===========================================================
244 * This is the DEV_ABORTIO vector of the device. It abort
245 * the given iorequest, and set
248 AROS_LH1(LONG, devAbortIO,
249 AROS_LHA(struct IOUsbHWReq *, ioreq, A1), LIBBASETYPEPTR, base, 6, ohci)
251 AROS_LIBFUNC_INIT
252 KPRINTF(50, ("devAbortIO ioreq: 0x%p, command %ld, status %ld\n",
253 ioreq, ioreq->iouh_Req.io_Command,
254 ioreq->iouh_Req.io_Message.mn_Node.ln_Type));
256 /* Is it pending? */
257 if (ioreq->iouh_Req.io_Message.mn_Node.ln_Type == NT_MESSAGE)
259 if (cmdAbortIO(ioreq, base))
261 return 0;
264 return -1;
266 AROS_LIBFUNC_EXIT}