revert between 56095 -> 55830 in arch
[AROS.git] / rom / usb / pciusbhc / ehci / pciehci_hci.c
blob4e2f277fff19152c93cbec3f4894aa7a6f6ca992
1 /*
2 Copyright © 2011-2012, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include LC_LIBDEFS_FILE
8 #include <devices/usb_hub.h>
10 #include "pciehci_hci.h"
11 #include "pciehci_uhw.h"
13 APTR pciGetPhysical(struct ehc_controller *ehc, APTR virtaddr) {
14 //struct PCIDevice *hd = hc->hc_Device;
15 return(HIDD_PCIDriver_CPUtoPCI(ehc->ehc_pcidriverobject, virtaddr));
18 static inline struct EhciQH * ehciAllocQH(struct ehc_controller *ehc) {
19 struct EhciQH *eqh = ehc->ehc_EhciQHPool;
21 if(!eqh) {
22 // out of QHs!
23 KPRINTF(20, ("Out of QHs!\n"));
24 return NULL;
27 ehc->ehc_EhciQHPool = (struct EhciQH *) eqh->eqh_Succ;
28 return(eqh);
31 static inline void ehciFreeQH(struct ehc_controller *ehc, struct EhciQH *eqh) {
32 eqh->eqh_Succ = ehc->ehc_EhciQHPool;
33 ehc->ehc_EhciQHPool = eqh;
36 static inline struct EhciTD * ehciAllocTD(struct ehc_controller *ehc) {
37 struct EhciTD *etd = ehc->ehc_EhciTDPool;
39 if(!etd) {
40 // out of TDs!
41 KPRINTF(20, ("Out of TDs!\n"));
42 return NULL;
45 ehc->ehc_EhciTDPool = (struct EhciTD *) etd->etd_Succ;
46 return(etd);
49 static inline void ehciFreeTD(struct ehc_controller *ehc, struct EhciTD *etd) {
50 etd->etd_Succ = ehc->ehc_EhciTDPool;
51 ehc->ehc_EhciTDPool = etd;
54 static AROS_INTH1(ehciResetHandler, struct ehc_controller *, ehc)
56 AROS_INTFUNC_INIT
58 CONSTWRITEREG32_LE(ehc->ehc_opregbase, EHCI_USBCMD, EHUF_HCRESET|(1UL<<EHUS_INTTHRESHOLD)); /* Resets the controller */
60 return FALSE;
62 AROS_INTFUNC_EXIT
65 void ehciFreeAsyncContext(struct ehc_controller *ehc, struct EhciQH *eqh) {
67 KPRINTF(5, ("Unlinking AsyncContext %08lx\n", eqh));
68 // unlink from schedule
69 eqh->eqh_Pred->eqh_NextQH = eqh->eqh_Succ->eqh_Self;
70 CacheClearE(&eqh->eqh_Pred->eqh_NextQH, 32, CACRF_ClearD);
71 SYNC;
73 eqh->eqh_Succ->eqh_Pred = eqh->eqh_Pred;
74 eqh->eqh_Pred->eqh_Succ = eqh->eqh_Succ;
75 SYNC;
77 // need to wait until an async schedule rollover before freeing these
78 Disable();
79 eqh->eqh_Succ = ehc->ehc_EhciAsyncFreeQH;
80 ehc->ehc_EhciAsyncFreeQH = eqh;
81 // activate doorbell
82 WRITEREG32_LE(ehc->ehc_opregbase, EHCI_USBCMD, ehc->ehc_EhciUsbCmd|EHUF_ASYNCDOORBELL);
83 Enable();
86 void ehciFreePeriodicContext(struct ehc_controller *ehc, struct EhciQH *eqh) {
88 struct EhciTD *etd;
89 struct EhciTD *nextetd;
91 KPRINTF(5, ("Unlinking PeriodicContext %08lx\n", eqh));
92 // unlink from schedule
93 eqh->eqh_Pred->eqh_NextQH = eqh->eqh_Succ->eqh_Self;
94 CacheClearE(&eqh->eqh_Pred->eqh_NextQH, 32, CACRF_ClearD);
95 SYNC;
97 eqh->eqh_Succ->eqh_Pred = eqh->eqh_Pred;
98 eqh->eqh_Pred->eqh_Succ = eqh->eqh_Succ;
99 SYNC;
101 Disable(); // avoid race condition with interrupt
102 nextetd = eqh->eqh_FirstTD;
103 while((etd = nextetd))
105 KPRINTF(1, ("FreeTD %08lx\n", nextetd));
106 nextetd = etd->etd_Succ;
107 ehciFreeTD(ehc, etd);
109 ehciFreeQH(ehc, eqh);
110 Enable();
113 void ehciFreeQHandTDs(struct ehc_controller *ehc, struct EhciQH *eqh) {
115 struct EhciTD *etd = NULL;
116 struct EhciTD *nextetd;
118 KPRINTF(5, ("Unlinking QContext %08lx\n", eqh));
119 nextetd = eqh->eqh_FirstTD;
120 while(nextetd) {
121 KPRINTF(1, ("FreeTD %08lx\n", nextetd));
122 etd = nextetd;
123 nextetd = (struct EhciTD *) etd->etd_Succ;
124 ehciFreeTD(ehc, etd);
127 ehciFreeQH(ehc, eqh);
130 void ehciUpdateIntTree(struct ehc_controller *ehc) {
132 struct EhciQH *eqh;
133 struct EhciQH *predeqh;
134 struct EhciQH *lastusedeqh;
135 UWORD cnt;
137 // optimize linkage between queue heads
138 predeqh = lastusedeqh = ehc->ehc_EhciTermQH;
139 for(cnt = 0; cnt < 11; cnt++) {
140 eqh = ehc->ehc_EhciIntQH[cnt];
141 if(eqh->eqh_Succ != predeqh) {
142 lastusedeqh = eqh->eqh_Succ;
144 eqh->eqh_NextQH = lastusedeqh->eqh_Self;
145 CacheClearE(&eqh->eqh_NextQH, 32, CACRF_ClearD);
146 predeqh = eqh;
150 BOOL ehciInit(struct ehc_controller *ehc, struct ehu_unit *ehu) {
151 return FALSE;