2 Copyright © 2014, The AROS Development Team. All rights reserved.
5 Desc: PCI XHCI USB host controller
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>
35 #include <hidd/hidd.h>
37 #include "pcixhci_intern.h"
39 #include LC_LIBDEFS_FILE
42 Keep this one short and simple...
44 static AROS_UFH3(void, GM_UNIQUENAME(Enumerator
), AROS_UFHA(struct Hook
*, hook
, A0
), AROS_UFHA(OOP_Object
*, pciDevice
, A2
), AROS_UFHA(APTR
, message
, A1
)) {
47 LIBBASETYPE
*LIBBASE
= (LIBBASETYPE
*)hook
->h_Data
;
49 mybug(-1, ("\n[PCIXHCI] Enumerator: Found PCI XHCI host controller\n"));
51 struct PCIXHCIUnit
*unit
;
52 static ULONG unitnum
= 0;
54 unit
= AllocVec(sizeof(struct PCIXHCIUnit
), MEMF_ANY
|MEMF_CLEAR
);
56 /* PCI device is useless for us if we can't obtain it */
57 if(HIDD_PCIDevice_Obtain(pciDevice
, LIBBASE
->library
.lib_Node
.ln_Name
) == NULL
) {
58 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_INTLine
, &unit
->hc
.intline
);
59 if(unit
->hc
.intline
!= 255) {
60 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_Bus
, &unit
->hc
.bus
);
61 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_Dev
, &unit
->hc
.dev
);
62 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_Sub
, &unit
->hc
.sub
);
63 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_Driver
, (APTR
)&unit
->hc
.pcidriver
);
64 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_Base0
, (APTR
)&unit
->hc
.capregbase
);
66 unit
->hc
.pcidevice
= pciDevice
;
67 unit
->pcixhcibase
= LIBBASE
;
68 unit
->number
= unitnum
++;
70 /* Get the serial number from PCIe Extended Capability when and if AROS gets the support for it */
72 AddTail(&LIBBASE
->unit_list
, (struct Node
*)unit
);
73 mybug(-1, ("[PCIXHCI] Enumerator: Host controller obtained\n"));
75 mybug(-1, ("[PCIXHCI] Enumerator: Host controller has bogus intline!\n"));
76 HIDD_PCIDevice_Release(pciDevice
);
80 mybug(-1, ("[PCIXHCI] Enumerator: Host controller could not be obtained\n"));
84 mybug(-1, ("\n[PCIXHCI] Enumerator: Failed to allocate unit structure!\n\n"));
90 BOOL
PCIXHCI_Discover(LIBBASETYPEPTR LIBBASE
) {
91 mybug(0, ("[PCIXHCI] PCIXHCI_Discover: Entering function\n"));
93 NEWLIST(&LIBBASE
->unit_list
);
95 static struct TagItem tags
[] = {
96 { tHidd_PCI_Class
, PCI_BASE_CLASS_SERIAL
},
97 { tHidd_PCI_SubClass
, PCI_SUB_CLASS_USB
},
98 { tHidd_PCI_Interface
, PCI_INTERFACE_XHCI
},
102 struct Hook FindHook
= {
103 h_Entry
: (IPTR (*)())GM_UNIQUENAME(Enumerator
),
107 HIDD_PCI_EnumDevices(LIBBASE
->pci
, &FindHook
, (struct TagItem
*)&tags
);
109 struct PCIXHCIUnit
*unit
;
111 ForeachNode(&LIBBASE
->unit_list
, unit
) {
112 if(!PCIXHCI_HCInit(unit
)) {
118 if(!IsListEmpty(&LIBBASE
->unit_list
)) {
119 mybug(-1, ("[PCIXHCI] Unit list is not empty\n"));
121 mybug(-1, ("[PCIXHCI] Unit list is empty\n"));
128 void PCIXHCI_Delay(struct PCIXHCIUnit
*unit
, ULONG msec
) {
129 /* Allocate a signal within this task context */
130 unit
->tr
->tr_node
.io_Message
.mn_ReplyPort
->mp_SigBit
= SIGB_SINGLE
;
131 unit
->tr
->tr_node
.io_Message
.mn_ReplyPort
->mp_SigTask
= FindTask(NULL
);
133 /* Specify the request */
134 unit
->tr
->tr_node
.io_Command
= TR_ADDREQUEST
;
135 unit
->tr
->tr_time
.tv_secs
= msec
/ 1000;
136 unit
->tr
->tr_time
.tv_micro
= 1000 * (msec
% 1000);
139 DoIO((struct IORequest
*)unit
->tr
);
141 unit
->tr
->tr_node
.io_Message
.mn_ReplyPort
->mp_SigTask
= NULL
;
144 BOOL
PCIXHCI_CreateTimer(struct PCIXHCIUnit
*unit
) {
145 mybug_unit(-1, ("Entering function\n"));
147 struct MsgPort
*mp
= NULL
;
149 mp
= CreateMsgPort();
151 unit
->tr
= (struct timerequest
*)CreateIORequest(mp
, sizeof(struct timerequest
));
153 FreeSignal(mp
->mp_SigBit
);
154 if (!OpenDevice((STRPTR
)"timer.device", UNIT_MICROHZ
, (struct IORequest
*)unit
->tr
, 0)) {
157 DeleteIORequest((struct IORequest
*)unit
->tr
);
158 mp
->mp_SigBit
= AllocSignal(-1);
166 void PCIXHCI_DeleteTimer(struct PCIXHCIUnit
*unit
) {
167 mybug_unit(-1, ("Entering function\n"));
170 unit
->tr
->tr_node
.io_Message
.mn_ReplyPort
->mp_SigBit
= AllocSignal(-1);
171 CloseDevice((struct IORequest
*)unit
->tr
);
172 DeleteMsgPort(unit
->tr
->tr_node
.io_Message
.mn_ReplyPort
);
173 DeleteIORequest((struct IORequest
*)unit
->tr
);