@@ -116,6 +116,52 @@ static inline void ehciReleaseDMABuffer(APTR dmabuffer, APTR original, ULONG len
116116#endif
117117}
118118
119+ static void ehciFillScatterGather (struct PCIController * hc ,struct EhciHCPrivate * ehcihcp ,
120+ struct EhciTD * etd ,APTR buffer ,ULONG length )
121+ {
122+ UBYTE * cursor = (UBYTE * )buffer ;
123+ IPTR phys ;
124+ ULONG remaining ;
125+ int idx ;
126+
127+ /* First buffer pointer can include the offset inside the physical page */
128+ phys = (IPTR )pciGetPhysical (hc ,cursor );
129+ ehciSetPointer (ehcihcp ,etd -> etd_BufferPtr [0 ],etd -> etd_ExtBufferPtr [0 ],phys );
130+
131+ /* Calculate how much of the first page is actually used */
132+ ULONG firstpage = EHCI_PAGE_SIZE - (phys & (EHCI_PAGE_SIZE - 1 ));
133+ if (firstpage > length )
134+ firstpage = length ;
135+
136+ remaining = (length > firstpage ) ?length - firstpage :0 ;
137+ cursor += firstpage ;
138+
139+ for (idx = 1 ;idx < 5 ;idx ++ )
140+ {
141+ if (!remaining )
142+ {
143+ WRITEMEM32_LE (& etd -> etd_BufferPtr [idx ],0 );
144+ #if __WORDSIZE == 64
145+ WRITEMEM32_LE (& etd -> etd_ExtBufferPtr [idx ],0 );
146+ #endif
147+ continue ;
148+ }
149+
150+ phys = (IPTR )pciGetPhysical (hc ,cursor )& EHCI_PAGE_MASK ;
151+ ehciSetPointer (ehcihcp ,etd -> etd_BufferPtr [idx ],etd -> etd_ExtBufferPtr [idx ],phys );
152+
153+ if (remaining > EHCI_PAGE_SIZE )
154+ {
155+ remaining -= EHCI_PAGE_SIZE ;
156+ }
157+ else
158+ {
159+ remaining = 0 ;
160+ }
161+ cursor += EHCI_PAGE_SIZE ;
162+ }
163+ }
164+
119165static void ehciFinishRequest (struct PCIUnit * unit ,struct IOUsbHWReq * ioreq )
120166{
121167struct EhciQH * eqh = ioreq -> iouh_DriverPrivate1 ;
@@ -381,12 +427,7 @@ void ehciHandleFinishedTDs(struct PCIController *hc) {
381427pciusbDebug ("EHCI" ,"Reload Bulk TD 0x%p len %ld (%ld/%ld) phy=0x%p\n" ,
382428etd ,len ,eqh -> eqh_Actual ,ioreq -> iouh_Length ,phyaddr );
383429WRITEMEM32_LE (& etd -> etd_CtrlStatus ,ctrlstatus |(len <<ETSS_TRANSLENGTH ));
384- // FIXME need quark scatter gather mechanism here
385- ehciSetPointer (ehcihcp ,etd -> etd_BufferPtr [0 ],etd -> etd_ExtBufferPtr [0 ],phyaddr );
386- ehciSetPointer (ehcihcp ,etd -> etd_BufferPtr [1 ],etd -> etd_ExtBufferPtr [1 ], (phyaddr & EHCI_PAGE_MASK )+ (1 * EHCI_PAGE_SIZE ));
387- ehciSetPointer (ehcihcp ,etd -> etd_BufferPtr [2 ],etd -> etd_ExtBufferPtr [2 ], (phyaddr & EHCI_PAGE_MASK )+ (2 * EHCI_PAGE_SIZE ));
388- ehciSetPointer (ehcihcp ,etd -> etd_BufferPtr [3 ],etd -> etd_ExtBufferPtr [3 ], (phyaddr & EHCI_PAGE_MASK )+ (3 * EHCI_PAGE_SIZE ));
389- ehciSetPointer (ehcihcp ,etd -> etd_BufferPtr [4 ],etd -> etd_ExtBufferPtr [4 ], (phyaddr & EHCI_PAGE_MASK )+ (4 * EHCI_PAGE_SIZE ));
430+ ehciFillScatterGather (hc ,ehcihcp ,etd , (UBYTE * )eqh -> eqh_Buffer + eqh -> eqh_Actual ,len );
390431
391432phyaddr += len ;
392433eqh -> eqh_Actual += len ;
@@ -790,12 +831,7 @@ void ehciScheduleCtrlTDs(struct PCIController *hc) {
790831 }
791832dataetd -> etd_Length = len ;
792833WRITEMEM32_LE (& dataetd -> etd_CtrlStatus ,ctrlstatus |(len <<ETSS_TRANSLENGTH ));
793- // FIXME need quark scatter gather mechanism here
794- ehciSetPointer (ehcihcp ,dataetd -> etd_BufferPtr [0 ],dataetd -> etd_ExtBufferPtr [0 ],phyaddr );
795- ehciSetPointer (ehcihcp ,dataetd -> etd_BufferPtr [1 ],dataetd -> etd_ExtBufferPtr [1 ], (phyaddr & EHCI_PAGE_MASK )+ (1 * EHCI_PAGE_SIZE ));
796- ehciSetPointer (ehcihcp ,dataetd -> etd_BufferPtr [2 ],dataetd -> etd_ExtBufferPtr [2 ], (phyaddr & EHCI_PAGE_MASK )+ (2 * EHCI_PAGE_SIZE ));
797- ehciSetPointer (ehcihcp ,dataetd -> etd_BufferPtr [3 ],dataetd -> etd_ExtBufferPtr [3 ], (phyaddr & EHCI_PAGE_MASK )+ (3 * EHCI_PAGE_SIZE ));
798- ehciSetPointer (ehcihcp ,dataetd -> etd_BufferPtr [4 ],dataetd -> etd_ExtBufferPtr [4 ], (phyaddr & EHCI_PAGE_MASK )+ (4 * EHCI_PAGE_SIZE ));
834+ ehciFillScatterGather (hc ,ehcihcp ,dataetd , (UBYTE * )eqh -> eqh_Buffer + eqh -> eqh_Actual ,len );
799835
800836phyaddr += len ;
801837eqh -> eqh_Actual += len ;
@@ -1013,12 +1049,7 @@ void ehciScheduleIntTDs(struct PCIController *hc) {
10131049 }
10141050etd -> etd_Length = len ;
10151051WRITEMEM32_LE (& etd -> etd_CtrlStatus ,ctrlstatus |(len <<ETSS_TRANSLENGTH ));
1016- // FIXME need quark scatter gather mechanism here
1017- ehciSetPointer (ehcihcp ,etd -> etd_BufferPtr [0 ],etd -> etd_ExtBufferPtr [0 ],phyaddr );
1018- ehciSetPointer (ehcihcp ,etd -> etd_BufferPtr [1 ],etd -> etd_ExtBufferPtr [1 ], (phyaddr & EHCI_PAGE_MASK )+ (1 * EHCI_PAGE_SIZE ));
1019- ehciSetPointer (ehcihcp ,etd -> etd_BufferPtr [2 ],etd -> etd_ExtBufferPtr [2 ], (phyaddr & EHCI_PAGE_MASK )+ (2 * EHCI_PAGE_SIZE ));
1020- ehciSetPointer (ehcihcp ,etd -> etd_BufferPtr [3 ],etd -> etd_ExtBufferPtr [3 ], (phyaddr & EHCI_PAGE_MASK )+ (3 * EHCI_PAGE_SIZE ));
1021- ehciSetPointer (ehcihcp ,etd -> etd_BufferPtr [4 ],etd -> etd_ExtBufferPtr [4 ], (phyaddr & EHCI_PAGE_MASK )+ (4 * EHCI_PAGE_SIZE ));
1052+ ehciFillScatterGather (hc ,ehcihcp ,etd , (UBYTE * )eqh -> eqh_Buffer + eqh -> eqh_Actual ,len );
10221053
10231054phyaddr += len ;
10241055eqh -> eqh_Actual += len ;
@@ -1195,12 +1226,7 @@ void ehciScheduleBulkTDs(struct PCIController *hc) {
11951226pciusbDebug ("EHCI" ,"Bulk TD 0x%p len %ld (%ld/%ld) phy=0x%p\n" ,
11961227etd ,len ,eqh -> eqh_Actual ,ioreq -> iouh_Length ,phyaddr );
11971228WRITEMEM32_LE (& etd -> etd_CtrlStatus ,ctrlstatus |(len <<ETSS_TRANSLENGTH ));
1198- // FIXME need quark scatter gather mechanism here
1199- ehciSetPointer (ehcihcp ,etd -> etd_BufferPtr [0 ],etd -> etd_ExtBufferPtr [0 ],phyaddr );
1200- ehciSetPointer (ehcihcp ,etd -> etd_BufferPtr [1 ],etd -> etd_ExtBufferPtr [1 ], (phyaddr & EHCI_PAGE_MASK )+ (1 * EHCI_PAGE_SIZE ));
1201- ehciSetPointer (ehcihcp ,etd -> etd_BufferPtr [2 ],etd -> etd_ExtBufferPtr [2 ], (phyaddr & EHCI_PAGE_MASK )+ (2 * EHCI_PAGE_SIZE ));
1202- ehciSetPointer (ehcihcp ,etd -> etd_BufferPtr [3 ],etd -> etd_ExtBufferPtr [3 ], (phyaddr & EHCI_PAGE_MASK )+ (3 * EHCI_PAGE_SIZE ));
1203- ehciSetPointer (ehcihcp ,etd -> etd_BufferPtr [4 ],etd -> etd_ExtBufferPtr [4 ], (phyaddr & EHCI_PAGE_MASK )+ (4 * EHCI_PAGE_SIZE ));
1229+ ehciFillScatterGather (hc ,ehcihcp ,etd , (UBYTE * )eqh -> eqh_Buffer + eqh -> eqh_Actual ,len );
12041230
12051231phyaddr += len ;
12061232eqh -> eqh_Actual += len ;