2 Copyright © 2014, The AROS Development Team. All rights reserved.
5 Desc: PCI XHCI USB host controller
14 #include <aros/debug.h>
15 #include <aros/macros.h>
16 #include <aros/asmcall.h>
17 #include <aros/symbolsets.h>
19 #include <proto/oop.h>
20 #include <proto/exec.h>
21 #include <proto/stdc.h>
22 #include <proto/arossupport.h>
24 #include <devices/usb.h>
25 #include <devices/usb_hub.h>
26 #include <devices/newstyle.h>
27 #include <devices/usbhardware.h>
33 #include <hidd/hidd.h>
35 #include "pcixhci_intern.h"
37 #include LC_LIBDEFS_FILE
39 static int GM_UNIQUENAME(Init
)(LIBBASETYPEPTR LIBBASE
) {
40 mybug(0,("[PCIXHCI] Init: Entering function\n"));
42 struct OOP_ABDescr attrbases
[] = {
43 { (STRPTR
)IID_Hidd
, &LIBBASE
->HiddAB
},
44 { (STRPTR
)IID_Hidd_PCIDevice
, &LIBBASE
->HiddPCIDeviceAB
},
48 if ((LIBBASE
->pci
= OOP_NewObject(NULL
, (STRPTR
)CLID_Hidd_PCI
, NULL
))) {
49 if(OOP_ObtainAttrBases(attrbases
)) {
50 return(PCIXHCI_Discover(LIBBASE
));
54 /* Someone here failed... */
55 OOP_ReleaseAttrBases(attrbases
);
56 OOP_DisposeObject(LIBBASE
->pci
);
58 mybug(0,("[PCIXHCI] Init: Failing...\n"));
62 static int GM_UNIQUENAME(Open
)(LIBBASETYPEPTR LIBBASE
, struct IOUsbHWReq
*ioreq
, ULONG unitnum
, ULONG flags
) {
63 mybug(0, ("[PCIXHCI] Open: Entering function\n"));
64 mybug(0, ("[PCIXHCI] Open: Unit %d\n", unitnum
));
66 struct PCIXHCIUnit
*unit
;
68 ioreq
->iouh_Req
.io_Unit
= NULL
;
69 ioreq
->iouh_Req
.io_Error
= IOERR_OPENFAIL
;
71 ForeachNode(&LIBBASE
->unit_list
, unit
) {
72 if(unit
->number
== unitnum
) {
73 mybug(0, (" Found unit from node list %s %p\n\n", unit
->name
, unit
));
75 if(ioreq
->iouh_Req
.io_Message
.mn_Length
< sizeof(struct IOUsbHWReq
)) {
76 mybug(-1, ("[PCIXHCI] Open: Invalid MN_LENGTH!\n"));
77 ioreq
->iouh_Req
.io_Error
= IOERR_BADLENGTH
;
81 ioreq
->iouh_Req
.io_Unit
= (struct Unit
*) unit
;
82 ioreq
->iouh_Req
.io_Message
.mn_Node
.ln_Type
= NT_REPLYMSG
;
83 ioreq
->iouh_Req
.io_Error
= 0;
92 static int GM_UNIQUENAME(Close
)(LIBBASETYPEPTR LIBBASE
, struct IOUsbHWReq
*ioreq
) {
93 mybug(0, ("[PCIXHCI] Close: Entering function\n"));
95 ioreq
->iouh_Req
.io_Unit
= (APTR
) -1;
96 ioreq
->iouh_Req
.io_Device
= (APTR
) -1;
101 static int GM_UNIQUENAME(Expunge
)(LIBBASETYPEPTR LIBBASE
) {
103 struct PCIXHCIUnit
*unit
;
105 ForeachNode(&LIBBASE
->unit_list
, unit
) {
106 HIDD_PCIDevice_Release(unit
->hc
.pcidevice
);
111 struct OOP_ABDescr attrbases
[] = {
112 { (STRPTR
)IID_Hidd
, &LIBBASE
->HiddAB
},
113 { (STRPTR
)IID_Hidd_PCIDevice
, &LIBBASE
->HiddPCIDeviceAB
},
117 OOP_ReleaseAttrBases(attrbases
);
118 OOP_DisposeObject(LIBBASE
->pci
);
123 ADD2INITLIB(GM_UNIQUENAME(Init
), 0)
124 ADD2OPENDEV(GM_UNIQUENAME(Open
), 0)
125 ADD2CLOSEDEV(GM_UNIQUENAME(Close
), 0)
126 ADD2EXPUNGELIB(GM_UNIQUENAME(Expunge
), 0)
128 AROS_LH1(void, BeginIO
, AROS_LHA(struct IOUsbHWReq
*, ioreq
, A1
), LIBBASETYPEPTR
, LIBBASE
, 5, PCIXHCI
) {
130 mybug(0, ("[PCIXHCI] BeginIO: Entering function\n"));
134 ioreq
->iouh_Req
.io_Message
.mn_Node
.ln_Type
= NT_MESSAGE
;
135 ioreq
->iouh_Req
.io_Error
= UHIOERR_NO_ERROR
;
137 struct PCIXHCIUnit
*unit
= (struct PCIXHCIUnit
*) ioreq
->iouh_Req
.io_Unit
;
141 switch (ioreq
->iouh_Req
.io_Command
) {
143 mybug_unit(0, ("CMD_RESET\n"));
146 mybug_unit(0, ("CMD_FLUSH\n"));
148 case UHCMD_QUERYDEVICE
:
149 mybug_unit(0, ("UHCMD_QUERYDEVICE\n"));
150 ret
= cmdQueryDevice(ioreq
);
153 mybug_unit(0, ("UHCMD_USBRESET\n"));
154 ret
= cmdUsbReset(ioreq
);
156 case UHCMD_USBRESUME
:
157 mybug_unit(0, ("UHCMD_USBRESUME\n"));
159 case UHCMD_USBSUSPEND
:
160 mybug_unit(0, ("UHCMD_USBSUSPEND\n"));
163 mybug_unit(0, ("UHCMD_USBOPER\n"));
164 //ret = cmdUsbOper(ioreq);
166 case UHCMD_CONTROLXFER
:
167 mybug_unit(0, ("UHCMD_CONTROLXFER unit %p %s\n", unit
, unit
->name
));
168 ret
= cmdControlXFer(ioreq
);
171 mybug_unit(0, ("UHCMD_BULKXFER\n"));
174 mybug_unit(0, ("UHCMD_INTXFER unit %p %s\n", unit
, unit
->name
));
175 ret
= cmdIntXFer(ioreq
);
178 mybug_unit(0, ("UHCMD_ISOXFER\n"));
181 /* Poseidon doesn't actually check this, ever... */
182 case NSCMD_DEVICEQUERY
:
183 mybug_unit(0, ("NSCMD_DEVICEQUERY\n"));
185 static const UWORD NSDSupported
[] = {
186 CMD_FLUSH
, CMD_RESET
,
200 struct NSDeviceQueryResult
*nsdq
= (struct NSDeviceQueryResult
*)((struct IOStdReq
*)(ioreq
))->io_Data
;
201 nsdq
->DevQueryFormat
= 0;
202 nsdq
->SizeAvailable
= sizeof(struct NSDeviceQueryResult
);
203 nsdq
->DeviceType
= NSDEVTYPE_USBHARDWARE
;
204 nsdq
->DeviceSubType
= 0;
205 nsdq
->SupportedCommands
= (UWORD
*)NSDSupported
;
209 mybug_unit(-1, ("IOERR_NOCMD\n"));
214 /* We have aborted the request as unit is invalid */
218 if(ret
!= RC_DONTREPLY
) {
219 /* Set error codes */
221 ioreq
->iouh_Req
.io_Error
= ret
& 0xff;
223 /* Terminate the iorequest */
224 ioreq
->iouh_Req
.io_Message
.mn_Node
.ln_Type
= NT_FREEMSG
;
225 /* If not quick I/O, reply the message */
226 if(!(ioreq
->iouh_Req
.io_Flags
& IOF_QUICK
)) {
227 ReplyMsg(&ioreq
->iouh_Req
.io_Message
);
234 AROS_LH1(LONG
, AbortIO
, AROS_LHA(struct IOUsbHWReq
*, ioreq
, A1
), LIBBASETYPEPTR
, LIBBASE
, 6, PCIXHCI
) {
236 mybug(-1, ("[PCIXHCI] AbortIO: Entering function\n"));
238 if(ioreq
->iouh_Req
.io_Message
.mn_Node
.ln_Type
== NT_MESSAGE
) {
239 if(cmdAbortIO(ioreq
)) {