A bit number was mistakenly used instead of a flag when setting notification
[AROS.git] / rom / usb / pciusbhc / ehci / pciehci_init.c
blob76e2fdcc4d777864cb6a8be3d61b69ce273e1d8c
1 /*
2 Copyright © 2011, The AROS Development Team. All rights reserved
3 $Id$
4 */
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))
13 AROS_USERFUNC_INIT
14 LIBBASETYPE *ehd = (LIBBASETYPE *) hook->h_Data;
16 BOOL Found = FALSE;
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) */
43 struct ehu_unit *ehu;
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))) {
52 Found = TRUE;
53 break;
58 /* Add the controller to the unit node or create a new one */
59 if(Found) {
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);
64 }else{
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;
78 }else{
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));
87 }else{
88 FreePooled(ehd->ehd_mempool, ehc, sizeof(struct ehc_controller));
91 }else{
92 FreePooled(ehd->ehd_mempool, ehc, sizeof(struct ehc_controller));
96 AROS_USERFUNC_EXIT
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 },
105 { NULL, NULL }
108 OOP_ObtainAttrBases(attrbases);
110 struct Hook pci_enumhooktag = {
111 h_Entry: (IPTR (*)()) ehc_enumhook,
112 h_Data: LIBBASE,
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 },
119 { TAG_DONE, 0UL }
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"));
147 return TRUE;
151 DeletePool(ehd->ehd_mempool);
152 ehd->ehd_mempool = NULL;
154 return FALSE;
157 static int Expunge(LIBBASETYPEPTR LIBBASE) {
158 LIBBASETYPE *ehd = (LIBBASETYPE *) LIBBASE;
160 DeletePool(ehd->ehd_mempool);
162 OOP_DisposeObject(ehd->ehd_pcihidd);
163 return TRUE;
166 ADD2INITLIB(Init,0)
167 ADD2EXPUNGELIB(Expunge,0)