Author: wmb Date: 2009-11-26 02:20:04 +0100 (Thu, 26 Nov 2009) New Revision: 1518
Modified: dev/usb2/hcd/ehci/qhtd.fth Log: OLPC trac 9423 - EHCI transfer completion - instead of checking the active bit in the transfer overlay, check it in the qtd, after verifying that the queue head has updated the current qtd pointer. This eliminates a race condition with the CPU looking at the transfer overlay before the EHCI host controller has performed the overlay.
Modified: dev/usb2/hcd/ehci/qhtd.fth =================================================================== --- dev/usb2/hcd/ehci/qhtd.fth 2009-11-26 00:31:26 UTC (rev 1517) +++ dev/usb2/hcd/ehci/qhtd.fth 2009-11-26 01:20:04 UTC (rev 1518) @@ -238,6 +238,8 @@ \ We start with OUT instead of PING here because some broken USB keys don't \ support PING. In bulk.fth, we add back the PING flag for bulk-out \ operations, where ping transactions can help significantly. + \ (I'm not sure this matters, as the overlay will overwrite it). + TD_TOGGLE_DATA1 TD_STAT_OUT or swap >hcqtd-token le-l! ( ) ;
@@ -532,21 +534,21 @@ ;
: qtd-done? ( qtd -- done? ) - >hcqtd-token le-l@ ( token ) - dup TD_STAT_HALTED and ( token halted? ) - swap TD_STAT_ACTIVE and 0= ( halted? inactive? ) - or ( done?' ) + >hcqtd-token le-l@ ( token ) + + dup TD_STAT_HALTED and if ( token ) + drop true exit + then ( token ) + TD_STAT_ACTIVE and 0= ( done? ) ;
-: poll-delay ( -- ) d# 50 " us" evaluate ; : qh-done? ( qh -- done? ) process-hc-status ( qh ) dup sync-qh ( qh ) - >hcqh-overlay qtd-done? ( done? ) + >hcqh-cur-pqtd le-l@ dup if qtd-done? then ( done? ) ;
: done? ( qh -- usberr ) - poll-delay \ This may be a VIA quirk - if we poll too soon, we never see the done bit begin dup qh-done? 0= while ( qh ) 1 ms dup >qh-timeout ( qh timeout-adr )