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 "pcixhci_controller.h"
41 #include LC_LIBDEFS_FILE
44 Keep this one short and simple...
46 static AROS_UFH3(void, GM_UNIQUENAME(Enumerator
), AROS_UFHA(struct Hook
*, hook
, A0
), AROS_UFHA(OOP_Object
*, pciDevice
, A2
), AROS_UFHA(APTR
, message
, A1
)) {
49 LIBBASETYPE
*LIBBASE
= (LIBBASETYPE
*)hook
->h_Data
;
51 mybug(-1, ("\n[PCIXHCI] Enumerator: Found PCI XHCI host controller\n"));
53 struct PCIXHCIUnit
*unit
;
54 static ULONG unitnum
= 0;
56 unit
= AllocVec(sizeof(struct PCIXHCIUnit
), MEMF_ANY
|MEMF_CLEAR
);
58 /* PCI device is useless for us if we can't obtain it */
59 if(HIDD_PCIDevice_Obtain(pciDevice
, LIBBASE
->library
.lib_Node
.ln_Name
) == NULL
) {
60 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_INTLine
, &unit
->hc
.intline
);
61 if(unit
->hc
.intline
!= 255) {
62 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_Bus
, &unit
->hc
.bus
);
63 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_Dev
, &unit
->hc
.dev
);
64 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_Sub
, &unit
->hc
.sub
);
65 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_Driver
, (APTR
)&unit
->hc
.pcidriver
);
67 /* Store capability base */
68 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_Base0
, (APTR
)&unit
->hc
.capability_base
);
69 /* Store operational base */
70 unit
->hc
.operational_base
= (APTR
) ((IPTR
) (unit
->hc
.capability_base
) + capability_readb(XHCI_CAPLENGTH
));
71 /* Store doorbell base */
72 unit
->hc
.doorbell_base
= (APTR
) ((IPTR
) (unit
->hc
.capability_base
) + XHCV_DBOFF(capability_readl(XHCI_DBOFF
)));
73 /* Store runtime base */
74 unit
->hc
.runtime_base
= (APTR
) ((IPTR
) (unit
->hc
.capability_base
) + XHCV_RTSOFF(capability_readl(XHCI_RTSOFF
)));
76 unit
->hc
.pcidevice
= pciDevice
;
77 unit
->pcixhcibase
= LIBBASE
;
78 unit
->number
= unitnum
++;
80 AddTail(&LIBBASE
->unit_list
, (struct Node
*)unit
);
81 mybug(-1, ("[PCIXHCI] Enumerator: Host controller obtained\n"));
83 mybug(-1, ("[PCIXHCI] Enumerator: Host controller has bogus intline!\n"));
84 HIDD_PCIDevice_Release(pciDevice
);
88 mybug(-1, ("[PCIXHCI] Enumerator: Host controller could not be obtained\n"));
92 mybug(-1, ("\n[PCIXHCI] Enumerator: Failed to allocate unit structure!\n\n"));
98 BOOL
PCIXHCI_Discover(LIBBASETYPEPTR LIBBASE
) {
99 mybug(0, ("[PCIXHCI] PCIXHCI_Discover: Entering function\n"));
101 NEWLIST(&LIBBASE
->unit_list
);
103 static struct TagItem tags
[] = {
104 { tHidd_PCI_Class
, PCI_BASE_CLASS_SERIAL
},
105 { tHidd_PCI_SubClass
, PCI_SUB_CLASS_USB
},
106 { tHidd_PCI_Interface
, PCI_INTERFACE_XHCI
},
110 struct Hook FindHook
= {
111 h_Entry
: (IPTR (*)())GM_UNIQUENAME(Enumerator
),
115 HIDD_PCI_EnumDevices(LIBBASE
->pci
, &FindHook
, (struct TagItem
*)&tags
);
117 struct PCIXHCIUnit
*unit
;
119 /* If the controller fails to init then remove it from our unit list */
120 ForeachNode(&LIBBASE
->unit_list
, unit
) {
121 if(!PCIXHCI_HCInit(unit
)) {
127 if(!IsListEmpty(&LIBBASE
->unit_list
)) {
128 mybug(-1, ("[PCIXHCI] Unit list is not empty\n"));
130 mybug(-1, ("[PCIXHCI] Unit list is empty\n"));