2 Copyright © 2011, The AROS Development Team. All rights reserved
6 #include LC_LIBDEFS_FILE
8 AROS_UFH3(void, ehc_enumhook
,
9 AROS_UFHA(struct Hook
*, hook
, A0
),
10 AROS_UFHA(OOP_Object
*, pcidevice
, A2
),
11 AROS_UFHA(APTR
, message
, A1
))
14 LIBBASETYPE
*ehd
= (LIBBASETYPE
*) hook
->h_Data
;
18 KPRINTF2(DBL_DEVIO
,("EHC Controller found...\n"));
20 struct ehc_controller
*ehc
;
21 if((ehc
= AllocPooled(ehd
->ehd_mempool
, sizeof(struct ehc_controller
)))) {
23 NEWLIST(&ehc
->ehc_CtrlXFerQueue
);
24 NEWLIST(&ehc
->ehc_IntXFerQueue
);
25 NEWLIST(&ehc
->ehc_IsoXFerQueue
);
26 NEWLIST(&ehc
->ehc_BulkXFerQueue
);
28 ehc
->ehc_devicebase
= ehd
;
29 ehc
->ehc_pcideviceobject
= pcidevice
;
31 OOP_GetAttr(pcidevice
, aHidd_PCIDevice_Driver
, (IPTR
*)&ehc
->ehc_pcidriverobject
);
33 OOP_GetAttr(pcidevice
, aHidd_PCIDevice_Bus
, &ehc
->ehc_pcibus
);
34 OOP_GetAttr(pcidevice
, aHidd_PCIDevice_Dev
, &ehc
->ehc_pcidev
);
35 OOP_GetAttr(pcidevice
, aHidd_PCIDevice_Sub
, &ehc
->ehc_pcisub
);
36 OOP_GetAttr(pcidevice
, aHidd_PCIDevice_INTLine
, &ehc
->ehc_intline
);
38 if(!(ehc
->ehc_intline
== 255)) {
40 /* Initialize EHCI controller */
42 /* Try to match the controller with previous unit nodes created based on the bus address (if any) */
45 struct Unitnode
* ehu_unitnode
;
46 if (!IsListEmpty(&ehd
->ehd_unitnodelist
)) {
48 ForeachNode(&ehd
->ehd_unitnodelist
, ehu_unitnode
) {
50 ehu
= (struct ehu_unit
*) ehu_unitnode
->ehu_unitptr
;
51 if(((ehu
->ehu_pcibus
== ehc
->ehc_pcibus
)&&(ehu
->ehu_pcidev
== ehc
->ehc_pcidev
))) {
58 /* Add the controller to the unit node or create a new one */
60 KPRINTF2(DBL_DEVIO
,("EHC Found matching unit #%ld (%04x:%04x)\n", ehu
->ehu_unitnumber
, ehu
->ehu_pcibus
, ehu
->ehu_pcidev
));
62 ehc
->ehc_unitptr
= ehu_unitnode
->ehu_unitptr
;
63 ADDTAIL((struct MinList
*) &ehu
->ehu_cntrlist
, (struct MinNode
*) &ehc
->ehc_contrnode
);
65 if((ehu
= AllocPooled(ehd
->ehd_mempool
, sizeof(struct ehu_unit
)))) {
66 ehu
->ehu_unitnode
.ehu_unitptr
= ehu
;
68 ehc
->ehc_unitptr
= ehu
;
70 ehu
->ehu_pcibus
= ehc
->ehc_pcibus
;
71 ehu
->ehu_pcidev
= ehc
->ehc_pcidev
;
73 if (!IsListEmpty(&ehd
->ehd_unitnodelist
)) {
74 struct Unitnode
*prev_ehu_unitnode
= (struct Unitnode
*) GetTail(&ehd
->ehd_unitnodelist
);
76 struct ehu_unit
*prev_ehu
= (struct ehu_unit
*) prev_ehu_unitnode
->ehu_unitptr
;
77 ehu
->ehu_unitnumber
= prev_ehu
->ehu_unitnumber
+ 1;
79 ehu
->ehu_unitnumber
= 0;
82 NEWLIST((struct MinList
*)&ehu
->ehu_cntrlist
);
83 ADDTAIL((struct MinList
*)&ehu
->ehu_cntrlist
, (struct MinNode
*) &ehc
->ehc_contrnode
);
84 ADDTAIL((struct MinList
*)&ehd
->ehd_unitnodelist
, (struct MinNode
*) &ehu
->ehu_unitnode
);
86 KPRINTF2(DBL_DEVIO
,("EHC Created new unit #%ld (%04x:%04x)\n", ehu
->ehu_unitnumber
, ehu
->ehu_pcibus
, ehu
->ehu_pcidev
));
88 FreePooled(ehd
->ehd_mempool
, ehc
, sizeof(struct ehc_controller
));
92 FreePooled(ehd
->ehd_mempool
, ehc
, sizeof(struct ehc_controller
));
99 static int Init(LIBBASETYPEPTR LIBBASE
) {
100 LIBBASETYPE
*ehd
= (LIBBASETYPE
*) LIBBASE
;
102 struct OOP_ABDescr attrbases
[] = {
103 { (STRPTR
)IID_Hidd
, &HiddAttrBase
},
104 { (STRPTR
)IID_Hidd_PCIDevice
, &HiddPCIDeviceAttrBase
},
108 OOP_ObtainAttrBases(attrbases
);
110 struct Hook pci_enumhooktag
= {
111 h_Entry
: (IPTR (*)()) ehc_enumhook
,
115 struct TagItem pci_enumtag
[] = {
116 { tHidd_PCI_Class
, PCI_BASE_CLASS_SERIAL
},
117 { tHidd_PCI_SubClass
, PCI_SUB_CLASS_USB
},
118 { tHidd_PCI_Interface
, PCI_INTERFACE_EHCI
},
122 NEWLIST((struct MinList
*)&ehd
->ehd_unitnodelist
);
124 if((ehd
->ehd_mempool
= CreatePool(MEMF_PUBLIC
| MEMF_CLEAR
| MEMF_SEM_PROTECTED
, 16384, 4096))) {
125 if((ehd
->ehd_pcihidd
= OOP_NewObject(NULL
, (STRPTR
) CLID_Hidd_PCI
, NULL
))) {
127 /* Enumerate all EHCI controllers */
128 HIDD_PCI_EnumDevices(ehd
->ehd_pcihidd
, &pci_enumhooktag
, (struct TagItem
*) &pci_enumtag
);
130 if (!IsListEmpty(&ehd
->ehd_unitnodelist
)) {
132 struct Unitnode
*ehu_unitnode
;
133 ForeachNode(&ehd
->ehd_unitnodelist
, ehu_unitnode
) {
135 struct ehu_unit
*ehu
= (struct ehu_unit
*)ehu_unitnode
->ehu_unitptr
;
136 if (!IsListEmpty(&ehu
->ehu_cntrlist
)) {
138 KPRINTF2(DBL_DEVIO
,("EHC Unit #%ld(%p) has controller(s)\n", ehu
->ehu_unitnumber
, ehu
->ehu_unitnode
.ehu_unitptr
));
140 struct ehc_controller
*ehc
;
141 ForeachNode(&ehu
->ehu_cntrlist
, ehc
) {
142 KPRINTF2(DBL_DEVIO
,("#%ld pointing to unit %p\n", ehc
->ehc_pcisub
, ehc
->ehc_unitptr
));
144 KPRINTF2(DBL_DEVIO
,("\n"));
151 DeletePool(ehd
->ehd_mempool
);
152 ehd
->ehd_mempool
= NULL
;
157 static int Expunge(LIBBASETYPEPTR LIBBASE
) {
158 LIBBASETYPE
*ehd
= (LIBBASETYPE
*) LIBBASE
;
160 DeletePool(ehd
->ehd_mempool
);
162 OOP_DisposeObject(ehd
->ehd_pcihidd
);
167 ADD2EXPUNGELIB(Expunge
,0)