Check for SYS/GL during library init. Reason is that
[AROS.git] / rom / usb / pciusbhc / xhci / pcixhci_device.c
blob14e8f0802a28d3d5ddd57b4738af2cb41a82e61e
1 /*
2 Copyright © 2014, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: PCI XHCI USB host controller
6 Lang: English
7 */
9 #ifdef DEBUG
10 #undef DEBUG
11 #endif
12 #define DEBUG 1
14 #include <aros/io.h>
15 #include <aros/debug.h>
16 #include <aros/macros.h>
17 #include <aros/asmcall.h>
18 #include <aros/symbolsets.h>
20 #include <proto/oop.h>
21 #include <proto/exec.h>
22 #include <proto/stdc.h>
23 #include <proto/arossupport.h>
25 #include <devices/usb.h>
26 #include <devices/usb_hub.h>
27 #include <devices/newstyle.h>
28 #include <devices/usbhardware.h>
29 #include <devices/timer.h>
31 #include <asm/io.h>
32 #include <inttypes.h>
34 #include <hidd/pci.h>
35 #include <hidd/hidd.h>
37 #include "pcixhci_intern.h"
39 #include LC_LIBDEFS_FILE
41 static int GM_UNIQUENAME(Init)(LIBBASETYPEPTR LIBBASE) {
42 mybug(0,("[PCIXHCI] Init: Entering function\n"));
44 struct OOP_ABDescr attrbases[] = {
45 { (STRPTR)IID_Hidd, &LIBBASE->HiddAB },
46 { (STRPTR)IID_Hidd_PCIDevice, &LIBBASE->HiddPCIDeviceAB },
47 { NULL, NULL }
50 if ((LIBBASE->pci = OOP_NewObject(NULL, (STRPTR)CLID_Hidd_PCI, NULL))) {
51 if(OOP_ObtainAttrBases(attrbases)) {
52 return(PCIXHCI_Discover(LIBBASE));
56 /* Someone here failed... */
57 OOP_ReleaseAttrBases(attrbases);
58 OOP_DisposeObject(LIBBASE->pci);
60 mybug(-1,("[PCIXHCI] Init: Failing...\n"));
61 return FALSE;
64 static int GM_UNIQUENAME(Open)(LIBBASETYPEPTR LIBBASE, struct IOUsbHWReq *ioreq, ULONG unitnum, ULONG flags) {
65 mybug(0, ("[PCIXHCI] Open: Entering function\n"));
66 mybug(0, ("[PCIXHCI] Open: Unit %d\n", unitnum));
68 struct PCIXHCIUnit *unit;
70 ioreq->iouh_Req.io_Unit = NULL;
71 ioreq->iouh_Req.io_Error = IOERR_OPENFAIL;
73 ForeachNode(&LIBBASE->unit_list, unit) {
74 if(unit->number == unitnum) {
75 mybug(0, (" Found unit from node list %s %p\n\n", unit->name, unit));
77 if(ioreq->iouh_Req.io_Message.mn_Length < sizeof(struct IOUsbHWReq)) {
78 mybug(-1, ("[PCIXHCI] Open: Invalid MN_LENGTH!\n"));
79 ioreq->iouh_Req.io_Error = IOERR_BADLENGTH;
80 return FALSE;
83 ioreq->iouh_Req.io_Unit = (struct Unit *) unit;
84 ioreq->iouh_Req.io_Message.mn_Node.ln_Type = NT_REPLYMSG;
85 ioreq->iouh_Req.io_Error = 0;
87 return TRUE;
91 return FALSE;
94 static int GM_UNIQUENAME(Close)(LIBBASETYPEPTR LIBBASE, struct IOUsbHWReq *ioreq) {
95 mybug(0, ("[PCIXHCI] Close: Entering function\n"));
97 ioreq->iouh_Req.io_Unit = (APTR) -1;
98 ioreq->iouh_Req.io_Device = (APTR) -1;
100 return TRUE;
103 static int GM_UNIQUENAME(Expunge)(LIBBASETYPEPTR LIBBASE) {
105 struct PCIXHCIUnit *unit = NULL;
106 struct PCIXHCIPort *port = NULL;
108 ForeachNode(&LIBBASE->unit_list, unit) {
109 ForeachNode(&unit->roothub.port_list, port) {
110 mybug_unit(-1, ("Deleting port %d named %s\n", port->number, port->name));
111 REMOVE(port);
112 FreeVec(port);
114 PCIXHCI_DeleteTimer(unit);
115 HIDD_PCIDevice_Release(unit->hc.pcidevice);
116 REMOVE(unit);
117 FreeVec(unit);
120 struct OOP_ABDescr attrbases[] = {
121 { (STRPTR)IID_Hidd, &LIBBASE->HiddAB },
122 { (STRPTR)IID_Hidd_PCIDevice, &LIBBASE->HiddPCIDeviceAB },
123 { NULL, NULL }
126 OOP_ReleaseAttrBases(attrbases);
127 OOP_DisposeObject(LIBBASE->pci);
129 return TRUE;
132 ADD2INITLIB(GM_UNIQUENAME(Init), 0)
133 ADD2OPENDEV(GM_UNIQUENAME(Open), 0)
134 ADD2CLOSEDEV(GM_UNIQUENAME(Close), 0)
135 ADD2EXPUNGELIB(GM_UNIQUENAME(Expunge), 0)
137 AROS_LH1(void, BeginIO, AROS_LHA(struct IOUsbHWReq *, ioreq, A1), LIBBASETYPEPTR, LIBBASE, 5, PCIXHCI) {
138 AROS_LIBFUNC_INIT
140 WORD ret = RC_OK;
142 ioreq->iouh_Req.io_Message.mn_Node.ln_Type = NT_MESSAGE;
143 ioreq->iouh_Req.io_Error = UHIOERR_NO_ERROR;
145 struct PCIXHCIUnit *unit = (struct PCIXHCIUnit *) ioreq->iouh_Req.io_Unit;
147 if(unit != NULL) {
149 switch (ioreq->iouh_Req.io_Command) {
150 case CMD_RESET:
151 mybug_unit(0, ("CMD_RESET\n"));
152 //ret = cmdReset(ioreq);
153 break;
154 case CMD_FLUSH:
155 mybug_unit(0, ("CMD_FLUSH\n"));
156 break;
157 case UHCMD_QUERYDEVICE:
158 mybug_unit(0, ("UHCMD_QUERYDEVICE\n"));
159 ret = cmdQueryDevice(ioreq);
160 break;
161 case UHCMD_USBRESET:
162 mybug_unit(0, ("UHCMD_USBRESET\n"));
163 ret = cmdUsbReset(ioreq);
164 break;
165 case UHCMD_USBRESUME:
166 mybug_unit(0, ("UHCMD_USBRESUME\n"));
167 break;
168 case UHCMD_USBSUSPEND:
169 mybug_unit(0, ("UHCMD_USBSUSPEND\n"));
170 break;
171 case UHCMD_USBOPER:
172 mybug_unit(0, ("UHCMD_USBOPER\n"));
173 //ret = cmdUsbOper(ioreq);
174 break;
175 case UHCMD_CONTROLXFER:
176 mybug_unit(0, ("UHCMD_CONTROLXFER unit %p %s\n", unit, unit->name));
177 ret = cmdControlXFer(ioreq);
178 break;
179 case UHCMD_BULKXFER:
180 mybug_unit(0, ("UHCMD_BULKXFER\n"));
181 break;
182 case UHCMD_INTXFER:
183 mybug_unit(0, ("UHCMD_INTXFER unit %p %s\n", unit, unit->name));
184 ret = cmdIntXFer(ioreq);
185 break;
186 case UHCMD_ISOXFER:
187 mybug_unit(0, ("UHCMD_ISOXFER\n"));
188 break;
190 /* Poseidon doesn't actually check this, ever... */
191 case NSCMD_DEVICEQUERY:
192 mybug_unit(0, ("NSCMD_DEVICEQUERY\n"));
194 static const UWORD NSDSupported[] = {
195 CMD_FLUSH, CMD_RESET,
196 UHCMD_QUERYDEVICE,
197 UHCMD_USBRESET,
198 UHCMD_USBRESUME,
199 UHCMD_USBSUSPEND,
200 UHCMD_USBOPER,
201 UHCMD_CONTROLXFER ,
202 UHCMD_ISOXFER,
203 UHCMD_INTXFER,
204 UHCMD_BULKXFER,
205 NSCMD_DEVICEQUERY,
209 struct NSDeviceQueryResult *nsdq = (struct NSDeviceQueryResult *)((struct IOStdReq *)(ioreq))->io_Data;
210 nsdq->DevQueryFormat = 0;
211 nsdq->SizeAvailable = sizeof(struct NSDeviceQueryResult);
212 nsdq->DeviceType = NSDEVTYPE_USBHARDWARE;
213 nsdq->DeviceSubType = 0;
214 nsdq->SupportedCommands = (UWORD *)NSDSupported;
215 ret = RC_OK;
216 break;
217 default:
218 mybug_unit(-1, ("IOERR_NOCMD\n"));
219 ret = IOERR_NOCMD;
220 break;
222 } else {
223 /* We have aborted the request as unit is invalid */
224 ret = IOERR_ABORTED;
227 if(ret != RC_DONTREPLY) {
228 /* Set error codes */
229 if (ret != RC_OK) {
230 ioreq->iouh_Req.io_Error = ret & 0xff;
232 /* Terminate the iorequest */
233 ioreq->iouh_Req.io_Message.mn_Node.ln_Type = NT_FREEMSG;
234 /* If not quick I/O, reply the message */
235 if(!(ioreq->iouh_Req.io_Flags & IOF_QUICK)) {
236 ReplyMsg(&ioreq->iouh_Req.io_Message);
240 AROS_LIBFUNC_EXIT
243 AROS_LH1(LONG, AbortIO, AROS_LHA(struct IOUsbHWReq *, ioreq, A1), LIBBASETYPEPTR, LIBBASE, 6, PCIXHCI) {
244 AROS_LIBFUNC_INIT
246 if(ioreq->iouh_Req.io_Message.mn_Node.ln_Type == NT_MESSAGE) {
247 if(cmdAbortIO(ioreq)) {
248 return(0);
252 return(-1);
253 AROS_LIBFUNC_EXIT