2 Copyright © 2011-2012, The AROS Development Team. All rights reserved.
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
;
23 KPRINTF(20, ("Out of QHs!\n"));
27 ehc
->ehc_EhciQHPool
= (struct EhciQH
*) eqh
->eqh_Succ
;
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
;
41 KPRINTF(20, ("Out of TDs!\n"));
45 ehc
->ehc_EhciTDPool
= (struct EhciTD
*) etd
->etd_Succ
;
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
)
58 CONSTWRITEREG32_LE(ehc
->ehc_opregbase
, EHCI_USBCMD
, EHUF_HCRESET
|(1UL<<EHUS_INTTHRESHOLD
)); /* Resets the controller */
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
);
73 eqh
->eqh_Succ
->eqh_Pred
= eqh
->eqh_Pred
;
74 eqh
->eqh_Pred
->eqh_Succ
= eqh
->eqh_Succ
;
77 // need to wait until an async schedule rollover before freeing these
79 eqh
->eqh_Succ
= ehc
->ehc_EhciAsyncFreeQH
;
80 ehc
->ehc_EhciAsyncFreeQH
= eqh
;
82 WRITEREG32_LE(ehc
->ehc_opregbase
, EHCI_USBCMD
, ehc
->ehc_EhciUsbCmd
|EHUF_ASYNCDOORBELL
);
86 void ehciFreePeriodicContext(struct ehc_controller
*ehc
, struct EhciQH
*eqh
) {
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
);
97 eqh
->eqh_Succ
->eqh_Pred
= eqh
->eqh_Pred
;
98 eqh
->eqh_Pred
->eqh_Succ
= eqh
->eqh_Succ
;
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
);
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
;
121 KPRINTF(1, ("FreeTD %08lx\n", nextetd
));
123 nextetd
= (struct EhciTD
*) etd
->etd_Succ
;
124 ehciFreeTD(ehc
, etd
);
127 ehciFreeQH(ehc
, eqh
);
130 void ehciUpdateIntTree(struct ehc_controller
*ehc
) {
133 struct EhciQH
*predeqh
;
134 struct EhciQH
*lastusedeqh
;
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
);
150 BOOL
ehciInit(struct ehc_controller
*ehc
, struct ehu_unit
*ehu
) {