Author: wmb Date: Wed Oct 12 00:28:40 2011 New Revision: 2591 URL: http://tracker.coreboot.org/trac/openfirmware/changeset/2591
Log: USB - Use interrupt-on-completion for bulk and control transfers, thus eliminating or at least greatly reducing problems related to descriptor polling causing DMA failures. Also use dma-push and dma-pull instead of dma-sync, for more precise control of coherency.
Modified: dev/usb2/align.fth dev/usb2/hcd/control.fth dev/usb2/hcd/ehci/bulk.fth dev/usb2/hcd/ehci/control.fth dev/usb2/hcd/ehci/ehci.fth dev/usb2/hcd/ehci/intr.fth dev/usb2/hcd/ehci/iso.fth dev/usb2/hcd/ehci/qhtd.fth dev/usb2/hcd/ohci/bulk.fth dev/usb2/hcd/ohci/control.fth dev/usb2/hcd/ohci/edtd.fth dev/usb2/hcd/ohci/intr.fth dev/usb2/hcd/uhci/bulk.fth dev/usb2/hcd/uhci/control.fth dev/usb2/hcd/uhci/intr.fth dev/usb2/hcd/uhci/qhtd.fth
Modified: dev/usb2/align.fth ============================================================================== --- dev/usb2/align.fth Tue Oct 11 23:59:39 2011 (r2590) +++ dev/usb2/align.fth Wed Oct 12 00:28:40 2011 (r2591) @@ -11,7 +11,8 @@ : round-up ( n align -- n' ) 1- tuck + swap invert and ;
external -: dma-sync ( virt phys size -- ) " dma-sync" $call-parent ; +: dma-push ( virt phys size -- ) " dma-push" $call-parent ; +: dma-pull ( virt phys size -- ) " dma-pull" $call-parent ; : dma-alloc ( size -- virt ) " dma-alloc" $call-parent ; : dma-free ( virt size -- ) " dma-free" $call-parent ; : dma-map-in ( virt size cache? -- phys ) " dma-map-in" $call-parent ;
Modified: dev/usb2/hcd/control.fth ============================================================================== --- dev/usb2/hcd/control.fth Tue Oct 11 23:59:39 2011 (r2590) +++ dev/usb2/hcd/control.fth Wed Oct 12 00:28:40 2011 (r2591) @@ -14,7 +14,7 @@ tuck >dr-value le-w! ( len idx vpcbp ) tuck >dr-index le-w! ( len vpcbp ) >dr-len le-w! ( ) - setup-buf setup-buf-phys /dr dma-sync ( ) + setup-buf setup-buf-phys /dr dma-push ( ) ;
external
Modified: dev/usb2/hcd/ehci/bulk.fth ============================================================================== --- dev/usb2/hcd/ehci/bulk.fth Tue Oct 11 23:59:39 2011 (r2590) +++ dev/usb2/hcd/ehci/bulk.fth Wed Oct 12 00:28:40 2011 (r2591) @@ -225,6 +225,7 @@ dup le-l@ ( in? token-adr token-val r: qtd qh ) rot if bulk-in-data@ else bulk-out-data@ then ( token-adr token-val toggle r: qtd qh ) or ( token-adr token-val' r: qtd qh ) + TD_IOC or ( token-adr token-val' r: qtd qh ) swap le-l! ( r: qtd qh )
r> r> ( qh qtd ) @@ -257,7 +258,7 @@ over >hcqtd-token ( qtd len token-adr ) tuck 2+ le-w! ( qtd token-adr ) TD_C_ERR3 TD_PID_OUT or TD_STAT_PING or TD_STAT_ACTIVE or swap le-w! ( qtd ) - sync-qtd + push-qtd ;
: wait-out ( qtd -- error? ) @@ -310,12 +311,12 @@ : bulk-in-ready? ( -- false | error true | buf actual 0 true ) clear-usb-error bulk-in-qtd >r - r@ sync-qtd + r@ pull-qtd r@ qtd-done? if ( ) r@ bulk-in-qh qtd-error? ?dup 0= if ( ) r@ >qtd-buf l@ ( buf actual ) r@ qtd-get-actual ( buf actual ) - 2dup r@ >qtd-pbuf l@ swap dma-sync ( buf actual ) + 2dup r@ >qtd-pbuf l@ swap dma-pull ( buf actual ) 0 ( buf actual 0 ) then ( error | buf actual 0 ) true ( ... ) @@ -352,7 +353,7 @@
\ Recycle the first qtd last so the transaction is atomic WRT the HC drop dup recycle-one-qtd ( qtd0 ) - sync-qtds + push-qtds ;
\ Fixup the host-controller-writable fields in the chain of qTDs - @@ -451,6 +452,12 @@
: recycle-buffer restart-bulk-in ;
+: start-bulk-transaction ( pid -- ) + my-bulk-qtd fill-bulk-io-qtds ( ) + my-bulk-qh pt-bulk fill-qh ( ) + my-bulk-qh interrupt-on-last-td ( ) + my-bulk-qh insert-qh ( ) +; : bulk-in ( buf len pipe -- actual usberr ) debug? if ." bulk-in" cr then dup to bulk-in-pipe @@ -459,22 +466,14 @@ bulk-in-timeout my-bulk-qh >qh-timeout l!
\ IN qTDs - TD_PID_IN my-bulk-qtd fill-bulk-io-qtds - - \ Start bulk in transaction - my-bulk-qh pt-bulk fill-qh - my-bulk-qh insert-qh + TD_PID_IN start-bulk-transaction ( )
\ Process results - my-bulk-qh done? if ( ) - 0 ( actual ) \ System error, timeout + my-bulk-qh done-error? if ( ) \ System error, timeout, or USB error + 0 ( actual ) else ( ) - my-bulk-qh error? if ( ) - 0 ( actual ) \ USB error - else ( ) - my-bulk-qtd dup my-#qtds get-actual ( qtd actual ) - over >qtd-buf l@ rot >qtd-pbuf l@ 2 pick dma-sync ( actual ) - then ( actual ) + my-bulk-qtd dup my-#qtds get-actual ( qtd actual ) + over >qtd-buf l@ rot >qtd-pbuf l@ 2 pick dma-pull ( actual ) then ( actual )
usb-error ( actual usberr ) @@ -486,9 +485,7 @@ 0 instance value bulk-out-busy? : done-bulk-out ( -- error? ) \ Process results - my-bulk-qh done? 0= if my-bulk-qh error? drop then - - usb-error ( usberr ) + my-bulk-qh done-error? ( usberr ) my-bulk-qtd map-out-bptrs ( usberr ) my-bulk-qh fixup-bulk-out-data ( usberr ) my-bulk-qh remove-qh ( usberr ) @@ -507,11 +504,7 @@ my-bulk-qh >hcqh-overlay >hcqtd-token dup le-l@ TD_STAT_PING or swap le-l!
\ OUT qTDs - TD_PID_OUT my-bulk-qtd fill-bulk-io-qtds ( ) - - \ Start bulk out transaction - my-bulk-qh pt-bulk fill-qh ( ) - my-bulk-qh insert-qh ( ) + TD_PID_OUT start-bulk-transaction ( ) true to bulk-out-busy? ( ) 0 ( usberr ) ;
Modified: dev/usb2/hcd/ehci/control.fth ============================================================================== --- dev/usb2/hcd/ehci/control.fth Tue Oct 11 23:59:39 2011 (r2590) +++ dev/usb2/hcd/ehci/control.fth Wed Oct 12 00:28:40 2011 (r2591) @@ -135,19 +135,16 @@
\ Start control transaction my-qh pt-ctrl fill-qh + my-qh interrupt-on-last-td my-qh insert-qh
\ Process results - my-qh done? if - 0 ( actual ) \ System error, timeout - else - my-qh error? if - 0 ( actual ) \ USB error - else - my-qtd >qtd-next l@ dup my-#qtds get-actual ( qtd actual ) - over >qtd-buf l@ rot >qtd-pbuf l@ 2 pick dma-sync ( actual ) - then - then + my-qh done-error? if ( ) + 0 ( actual ) \ System error, timeout, or USB error + else ( ) + my-qtd >qtd-next l@ dup my-#qtds get-actual ( qtd actual ) + over >qtd-buf l@ rot >qtd-pbuf l@ 2 pick dma-pull ( actual ) + then ( actual )
my-qh dup remove-qh free-qh ( actual ) usb-error ( actual usberr ) @@ -156,13 +153,12 @@ : run-control ( -- usberr ) \ Start control transaction my-qh pt-ctrl fill-qh + my-qh interrupt-on-last-td my-qh insert-qh
\ Process results - my-qh done? 0= if my-qh error? drop then - - my-qh dup remove-qh free-qh - usb-error + my-qh done-error? ( usberr ) + my-qh dup remove-qh free-qh ( usberr ) ;
: (control-set) ( sbuf sphy slen buf phy len -- usberr )
Modified: dev/usb2/hcd/ehci/ehci.fth ============================================================================== --- dev/usb2/hcd/ehci/ehci.fth Tue Oct 11 23:59:39 2011 (r2590) +++ dev/usb2/hcd/ehci/ehci.fth Wed Oct 12 00:28:40 2011 (r2591) @@ -69,6 +69,16 @@ usbsts@ dup usbsts! \ Clear interrupts and errors h# 10 and if " Host system error" USB_ERR_HCHALTED set-usb-error then ; +: hc-interrupt? ( -- interrupt? ) + usbsts@ h# 13 and dup if ( status ) + dup usbsts! ( status ) \ Clear interrupts, frame rollover, errors + dup h# 10 and if ( status ) + " USB host controller halted" USB_ERR_HCHALTED set-usb-error + then ( status ) + then ( status ) + 0<> ( interrupt? ) +; + : get-hc-status ( -- status ) usbsts@ dup usbsts! \ Clear interrupts and errors dup h# 10 and if " Host system error" USB_ERR_HCHALTED set-usb-error then
Modified: dev/usb2/hcd/ehci/intr.fth ============================================================================== --- dev/usb2/hcd/ehci/intr.fth Tue Oct 11 23:59:39 2011 (r2590) +++ dev/usb2/hcd/ehci/intr.fth Wed Oct 12 00:28:40 2011 (r2591) @@ -36,6 +36,8 @@ 2 pick over d# 16 << or ( dir qtd /bptr token ) TD_C_ERR3 or TD_STAT_ACTIVE or ( dir qtd /bptr token' ) intr-in-data@ toggle-intr-in-data or ( dir qtd /bptr token' ) +\ See the comment about Interrupt-On-Completion elsewhere in this file +\ i my-#qtds 1- = if TD_IOC or then ( dir qtd /bptr token' ) 2 pick >hcqtd-token le-l! ( dir qtd /bptr ) my-buf++ ( dir qtd ) dup fixup-last-qtd ( dir qtd ) @@ -66,18 +68,28 @@ : intr-in? ( -- actual usberr ) intr-in-qh 0= if 0 USB_ERR_INV_OP exit then ( ) clear-usb-error ( ) - intr-in-qh qh-done? if ( ) - intr-in-qh error? if ( ) - 0 ( actual ) + \ Ironically, we can't use Interrupt-On-Completion for interrupt pipes, + \ because when a bulk or control transaction is performed with IOC, the + \ call to hc-interrupt? from that transaction can prevent this routine + \ from seeing its IOC completion status. The "right" solution might be to + \ scan all queue heads on an IOC "interrupt", then set a flag in the private + \ area of the queue head. It's unclear that that is better for interrupt + \ pipes than just polling, since the polling typically happens on a timer + \ and thus is relatively infrequent. + \ If we were to use Interrupt-On-Completion for interrupt pipes, we would + \ use "intr-qh-done?" instead of "qh-done?" here. + intr-in-qh qh-done? 0= if ( ) + 0 usb-error ( actual usberr ) \ Timeout or system error + else ( ) + intr-in-qh qh-error? if ( ) + 0 ( actual ) \ USB error else ( ) - intr-in-qh sync-qhqtds ( ) + intr-in-qh pull-qhqtds ( ) intr-in-qtd intr-in-qh >qh-#qtds l@ get-actual ( actual ) - intr-in-qtd >qtd-buf intr-in-qtd >qtd-pbuf l@ 2 pick dma-sync ( actual ) + intr-in-qtd >qtd-buf intr-in-qtd >qtd-pbuf l@ 2 pick dma-pull ( actual ) then ( actual ) usb-error ( actual usberr ) intr-in-qh fixup-intr-in-data ( actual usberr ) - else ( ) - 0 usb-error ( actual usberr ) then ( actual usberr ) ;
@@ -87,6 +99,8 @@ dup >hcqtd-bptr0 dup le-l@ h# ffff.f000 and swap le-l! dup >qtd-/buf l@ d# 16 << TD_STAT_ACTIVE or TD_C_ERR3 or TD_PID_IN or +\ See the comment about Interrupt-On-Completion elsewhere in this file +\ TD_IOC or intr-in-data@ or over >hcqtd-token le-l! >qtd-next l@ @@ -104,7 +118,7 @@ intr-in-timeout intr-in-qh >qh-timeout l! intr-in-qh >hcqh-endp-char dup le-l@ QH_TD_TOGGLE invert and swap le-l! intr-in-qtd >qtd-phys l@ intr-in-qh >hcqh-overlay >hcqtd-next le-l! - intr-in-qh sync-qhqtds + intr-in-qh push-qhqtds ;
: end-intr-in ( -- )
Modified: dev/usb2/hcd/ehci/iso.fth ============================================================================== --- dev/usb2/hcd/ehci/iso.fth Tue Oct 11 23:59:39 2011 (r2590) +++ dev/usb2/hcd/ehci/iso.fth Wed Oct 12 00:28:40 2011 (r2591) @@ -174,7 +174,7 @@ else \ Link and replace the entry itd-struct >itd-link le-l! ( itd-phys ) ( R: idx ) then - itd-struct over /itd-sync dma-sync ( itd-phys ) ( R: idx ) + itd-struct over /itd-sync dma-push ( itd-phys ) ( R: idx ) TYP_ITD or r> framelist! ( ) ;
@@ -246,7 +246,7 @@ clear-usb-error iso-in-cur-itd set-itd-struct ( adr len ) itd-struct >itd-frame @ wait-frame-safe ( adr len ) - itd-struct dup >itd-phys @ /itd-sync dma-sync + itd-struct dup >itd-phys @ /itd-sync dma-pull iso-in-uframe-cnt 7 and ( adr len uframe# ) 4 * itd-struct >itd-xstat + le-l@ ( adr len xstat ) dup ITD_ACTIVE and if 3drop false exit then \ Not done yet @@ -295,14 +295,14 @@
[ifndef] notdef \ Debug aids -: ldump ( adr len -- ) " ldump" evaluate ; +: sys-ldump ( adr len -- ) " ldump" evaluate ; : .itd ( -- ) - iso-in-itd iso-in-#itd /itd-struct * ldump + iso-in-itd iso-in-#itd /itd-struct * sys-ldump ; : .xstat ( -- ) iso-in-#itd 0 do i set-itd-struct - itd-struct >itd-xstat /itd-xstat ldump + itd-struct >itd-xstat /itd-xstat sys-ldump loop ; \ Debug aids for video streaming only (and only if ITD_ACTIVE are all 0s)
Modified: dev/usb2/hcd/ehci/qhtd.fth ============================================================================== --- dev/usb2/hcd/ehci/qhtd.fth Tue Oct 11 23:59:39 2011 (r2590) +++ dev/usb2/hcd/ehci/qhtd.fth Wed Oct 12 00:28:40 2011 (r2591) @@ -189,10 +189,14 @@ \ QH and its list of TDs are allocated as needed. \ ---------------------------------------------------------------------------
-: sync-qh ( qh -- ) dup >qh-phys l@ /hcqh dma-sync ; -: sync-qtd ( qtd -- ) dup >qtd-phys l@ /hcqtd dma-sync ; -: sync-qtds ( qtd -- ) dup >qtd-phys l@ over >qtd-size l@ dma-sync ; -: sync-qhqtds ( qh -- ) dup >qh-phys l@ over >qh-size l@ dma-sync ; +: push-qh ( qh -- ) dup >qh-phys l@ /hcqh dma-push ; +: pull-qh ( qh -- ) dup >qh-phys l@ /hcqh dma-pull ; +: push-qtd ( qtd -- ) dup >qtd-phys l@ /hcqtd dma-push ; +: pull-qtd ( qtd -- ) dup >qtd-phys l@ /hcqtd dma-pull ; +: push-qtds ( qtd -- ) dup >qtd-phys l@ over >qtd-size l@ dma-push ; +: pull-qtds ( qtd -- ) dup >qtd-phys l@ over >qtd-size l@ dma-pull ; +: push-qhqtds ( qh -- ) dup >qh-phys l@ over >qh-size l@ dma-push ; +: pull-qhqtds ( qh -- ) dup >qh-phys l@ over >qh-size l@ dma-pull ;
: map-out-bptrs ( qtd -- ) dup >qtd-buf l@ over >qtd-pbuf l@ rot >qtd-/buf-all l@ hcd-map-out @@ -214,27 +218,6 @@ TERMINATE swap >hcqtd-next-alt le-l! ( ) ;
-: alloc-qtds ( #qtds -- qtd ) - dup >r /qtd * dup >r ( len ) ( R: #qtds len ) - aligned32-alloc-map-in ( u v p ) ( R: #qtds len ) - swap ( u p v ) ( R: #qtds len ) - dup r@ erase ( u p v ) ( R: #qtds len ) - - \ Record QTD size for later freeing - rot over >qtd-unaligned l! ( p v ) ( R: #qtds len ) - r> over >qtd-size l! ( p v ) ( R: #qtds ) - - dup rot r> link-qtds ( qtd.v ) -; - -: free-qtds ( qtd -- ) - >r ( R: qtd ) - r@ >qtd-unaligned l@ ( u ) ( R: qtd ) - r@ dup >qtd-phys l@ ( u v p ) ( R: qtd ) - r> >qtd-size l@ ( u v p size ) - aligned32-free-map-out ( ) -; - : link-qhqtd ( qtd.p qh -- ) >hcqh-overlay tuck ( qh.overlay qtd.p qh.overlay ) >hcqtd-next le-l! ( qh.overlay ) @@ -261,14 +244,6 @@ >qh-unaligned l! ( ) ;
-: alloc-qh ( -- qh ) - /qh aligned32-alloc-map-in ( u v p ) - over /qh erase ( u v p ) - over >r ( u v p r: v ) - /qh 0 init-qh ( r: v ) - TERMINATE r@ link-qhqtd ( r: v ) - r> ( qh.v ) -; : free-qh ( qh -- ) >r ( R: qh ) r@ >qh-unaligned l@ ( qh.u ) ( R: qh ) @@ -375,9 +350,22 @@ : link-to-qh-ptr ( qh -- ) dup qh-ptr >qh-next l! ( qh ) dup >qh-phys l@ TYP_QH or qh-ptr >hcqh-next le-l! ( qh ) - sync-qhqtds ( ) + push-qhqtds ( ) ; +: interrupt-on-last-td ( qh -- ) + /qh + ( qtd ) + begin ( qtd ) + dup >hcqtd-next le-l@ TERMINATE <> ( qtd flag ) + while ( qtd ) + >qtd-next l@ ( qtd' ) + repeat ( qtd ) + >hcqtd-token ( 'token ) + dup le-l@ TD_IOC or swap le-l! ( ) +; + : insert-qh ( qh -- ) + hc-interrupt? drop \ Clear any pending transfer-complete interrupts + 0 >hcqh-cur-pqtd off qh-ptr if ( qh ) \ If there is another qh, link the new qh to the existing qh head. qh-ptr over >qh-prev l! ( qh ) @@ -386,7 +374,7 @@
link-to-qh-ptr ( )
- qh-ptr sync-qh ( ) + qh-ptr push-qh ( ) else ( ) \ If there is no other qh, make it the head, link it to itself, \ and start the asynch schedule. @@ -431,7 +419,7 @@ dup >qh-prev l@ ?dup if ( qh prev.qh ) over >hcqh-next le-l@ over >hcqh-next le-l! over >qh-next l@ swap >qh-next l! - dup sync-qh + dup push-qh dup >qh-next l@ qh-ptr <> if dup >qh-prev l@ swap >qh-next l@ >qh-prev l! else @@ -442,7 +430,7 @@ qh-ptr >hcqh-endp-char dup le-l@ QH_HEAD or swap le-l! ( qh ) fix-wraparound-qh ( ) 0 qh-ptr >qh-prev l! ( ) - qh-ptr sync-qh + qh-ptr push-qh then ring-doorbell then @@ -540,40 +528,61 @@ ;
: qtd-done? ( qtd -- done? ) - >hcqtd-token le-l@ ( token ) - - dup TD_STAT_HALTED and if ( token ) - drop true exit - then ( token ) - TD_STAT_ACTIVE and 0= ( done? ) + >hcqtd-token le-l@ TD_STAT_ACTIVE and 0= ;
+[ifdef] notdef +\ This version looks for the ending condition in the transfer overlay : qh-done? ( qh -- done? ) - process-hc-status ( qh ) - dup sync-qh ( qh ) - >hcqh-cur-pqtd le-l@ dup if qtd-done? then ( done? ) -; - -true value delay? -: poll-delay ( -- ) d# 300 " us" evaluate ; -: done? ( qh -- usberr ) - delay? if poll-delay then - begin dup qh-done? 0= while ( qh ) - 1 ms - dup >qh-timeout ( qh timeout-adr ) - dup l@ 1- ( qh timeout-adr timeout' ) - dup rot l! ( qh timeout' ) - 0= if ( qh ) -delay? 0= if cr 7 emit 7 emit ." TIMEOUT" cr debug-me then - " Timeout" USB_ERR_TIMEOUT set-usb-error ( qh ) - drop ( ) - usb-error ( usberr ) - exit - then - repeat ( qh ) - drop ( ) + hc-interrupt? 0= if drop false exit then ( qh ) + dup pull-qh ( qh ) + dup >hcqh-cur-pqtd l@ 0= if ( qh ) + drop false exit ( -- done? ) + then ( qh ) + >hcqh-overlay ( qtd ) + dup >hcqtd-token le-l@ ( qtd token ) + dup TD_STAT_ACTIVE and if ( qtd token ) + 2drop false ( done? ) + else ( qtd token ) + TD_STAT_HALTED and if ( qtd ) + drop true ( done? ) + else ( qtd ) + >hcqtd-next le-l@ ( next ) + TERMINATE = ( done? ) + then ( done? ) + then ( done? ) +; +[then]
- usb-error ( usberr ) +\ This version traverses the list of QTDs, looking for an ending condition +: qh-done? ( qh -- done? ) + dup pull-qh ( qh ) +\ d# 30 us ( qh ) + /qh + ( qtd ) + begin ( qtd ) + dup >hcqtd-token le-l@ ( qtd token ) + dup TD_STAT_ACTIVE and 0= ( qtd token qtd-complete? ) + while ( qtd token ) + \ This QTD is complete - it is the end of the list if either + \ the next field is TERMINATE or if the HALTED bit is set + TD_STAT_HALTED and if ( qtd ) + drop true exit ( -- done? ) + then ( qtd ) + dup >hcqtd-next le-l@ TERMINATE = if ( qtd ) + drop true exit ( -- done? ) + then ( qtd ) + /qtd + ( qtd' ) + repeat ( qtd token ) + \ If we get here, we hit a QTD that is still active + 2drop false ( done? ) +; + +: intr-qh-done? ( qh -- done? ) + hc-interrupt? if ( qh ) + qh-done? ( done? ) + else ( qh ) + drop false ( done? ) + then ( done? ) ;
: qtd-error? ( qtd qh -- usberr ) @@ -583,11 +592,27 @@ usb-error ;
-: error? ( qh -- usberr ) dup >hcqh-overlay swap qtd-error? ; +: qh-error? ( qh -- usberr ) dup >hcqh-overlay swap qtd-error? ; + +: done-error? ( qh -- usberr ) + dup >qh-timeout l@ get-msecs + ( qh timeout ) + begin over intr-qh-done? 0= while ( qh timeout ) + usb-error ?dup if ." USB ERROR " . cr then + dup get-msecs - 0< if ( qh timeout ) + " Timeout" USB_ERR_TIMEOUT set-usb-error ( qh timeout ) + 2drop ( ) + usb-error ( usberr ) + exit + then ( qh timeout ) + repeat ( qh timeout ) + drop ( qh ) + + qh-error? ( usberr ) +;
: get-actual ( qtd #qtd -- actual ) 0 -rot 0 ?do ( actual qtd ) - dup sync-qtd ( actual qtd ) + dup pull-qtd ( actual qtd ) dup >hcqtd-token le-l@ dup TD_STAT_ACTIVE and 0= if over >qtd-/buf l@ ( actual qtd token len ) swap d# 16 >> h# 7fff and - ( actual qtd len' ) @@ -601,7 +626,7 @@
: qtd-get-actual ( qtd -- actual ) 0 swap begin ( actual qtd ) - dup sync-qtd ( actual qtd ) + dup pull-qtd ( actual qtd ) dup >hcqtd-token le-l@ dup TD_STAT_ACTIVE and 0= if over >qtd-/buf l@ ( actual qtd token len ) swap d# 16 >> h# 7fff and - ( actual qtd len' )
Modified: dev/usb2/hcd/ohci/bulk.fth ============================================================================== --- dev/usb2/hcd/ohci/bulk.fth Tue Oct 11 23:59:39 2011 (r2590) +++ dev/usb2/hcd/ohci/bulk.fth Wed Oct 12 00:28:40 2011 (r2591) @@ -79,7 +79,7 @@ ( ed ) dup >hced-tdhead le-l@ ( dir ed head ) rot ED_DIR_IN = if bulk-in-data@ else bulk-out-data@ then or over >hced-tdhead le-l! ( ed ) - ( ed ) sync-edtds + ( ed ) push-edtds ; : insert-my-bulk ( ed dir -- ) over fill-bulk-ed insert-bulk ; : insert-my-bulk-in ( ed -- ) ED_DIR_IN insert-my-bulk ; @@ -108,12 +108,12 @@ : bulk-in-ready? ( -- false | error true | buf actual 0 true ) clear-usb-error ( ) process-hc-status ( ) - bulk-in-ed dup sync-edtds ( ed ) + bulk-in-ed dup pull-edtds ( ed ) ed-done? if ( ) bulk-in-td error? ?dup 0= if ( ) bulk-in-td >td-cbp l@ ( buf ) bulk-in-td get-actual ( buf actual ) - 2dup bulk-in-td >td-pcbp l@ swap dma-sync ( buf actual ) + 2dup bulk-in-td >td-pcbp l@ swap dma-pull ( buf actual ) 0 ( buf actual 0 ) then ( error | buf actual 0 ) bulk-in-ed fixup-bulk-in-data ( error | buf actual 0 ) @@ -126,13 +126,13 @@ bulk-in-ed 0= if 0 USB_ERR_INV_OP exit then clear-usb-error ( ) process-hc-status ( ) - bulk-in-ed dup sync-edtds ( ed ) + bulk-in-ed dup pull-edtds ( ed ) ed-done? if ( ) bulk-in-td error? if 0 ( actual ) else bulk-in-td dup get-actual ( td actual ) - over >td-cbp l@ rot >td-pcbp l@ 2 pick dma-sync ( actual ) + over >td-cbp l@ rot >td-pcbp l@ 2 pick dma-pull ( actual ) then usb-error ( actual usberr ) bulk-in-ed fixup-bulk-in-data ( actual usberr ) @@ -165,7 +165,7 @@
\ Setup ED again bulk-in-td >td-phys l@ bulk-in-data@ or bulk-in-ed >hced-tdhead le-l! - bulk-in-ed dup sync-edtds + bulk-in-ed dup push-edtds ed-unset-skip enable-bulk ; @@ -198,7 +198,7 @@ 0 ( actual ) \ USB error else my-td dup get-actual ( td actual ) - over >td-cbp l@ rot >td-pcbp l@ 2 pick dma-sync ( actual ) + over >td-cbp l@ rot >td-pcbp l@ 2 pick dma-pull ( actual ) then then
Modified: dev/usb2/hcd/ohci/control.fth ============================================================================== --- dev/usb2/hcd/ohci/control.fth Tue Oct 11 23:59:39 2011 (r2590) +++ dev/usb2/hcd/ohci/control.fth Wed Oct 12 00:28:40 2011 (r2591) @@ -105,7 +105,7 @@
: insert-my-control ( -- ) my-ed dup fill-control-ed - dup sync-edtds + dup push-edtds insert-control ;
@@ -146,7 +146,7 @@ 0 ( actual ) \ USB error else my-td >td-next l@ dup get-actual ( td actual ) - over >td-cbp l@ rot >td-pcbp l@ 2 pick dma-sync ( actual ) + over >td-cbp l@ rot >td-pcbp l@ 2 pick dma-pull ( actual ) then then
Modified: dev/usb2/hcd/ohci/edtd.fth ============================================================================== --- dev/usb2/hcd/ohci/edtd.fth Tue Oct 11 23:59:39 2011 (r2590) +++ dev/usb2/hcd/ohci/edtd.fth Wed Oct 12 00:28:40 2011 (r2591) @@ -45,7 +45,7 @@
\ Initialize hcca hcca /hcca erase - hcca hcca-phys /hcca dma-sync + hcca hcca-phys /hcca dma-push ;
\ --------------------------------------------------------------------------- @@ -138,7 +138,7 @@ dup >hced-control dup le-l@ ED_SKIP_MASK invert and r> or swap le-l! - dup >ed-phys l@ /hced dma-sync + dup >ed-phys l@ /hced dma-push ; : ed-set-skip ( ed -- ) ED_SKIP_ON (set-skip) ; : ed-unset-skip ( ed -- ) ED_SKIP_OFF (set-skip) ; @@ -269,10 +269,15 @@ r> >ed-size l@ ( ed.u,v,p size ) aligned32-free-map-out ( ) ; -: sync-edtds ( ed -- ) +: push-edtds ( ed -- ) dup >ed-phys l@ ( ed.v,p ) over >ed-size l@ ( ed.v,p len ) - dma-sync ( ) + dma-push ( ) +; +: pull-edtds ( ed -- ) + dup >ed-phys l@ ( ed.v,p ) + over >ed-size l@ ( ed.v,p len ) + dma-pull ( ) ; : map-out-cbp ( td -- ) dup >td-cbp l@ over >td-pcbp l@ rot >td-/cbp-all l@ hcd-map-out @@ -429,7 +434,7 @@ : done? ( ed -- error? ) begin process-hc-status - dup sync-edtds + dup pull-edtds dup ed-done? ?dup 0= if 1 ms timeout 1- dup to timeout 0=
Modified: dev/usb2/hcd/ohci/intr.fth ============================================================================== --- dev/usb2/hcd/ohci/intr.fth Tue Oct 11 23:59:39 2011 (r2590) +++ dev/usb2/hcd/ohci/intr.fth Wed Oct 12 00:28:40 2011 (r2591) @@ -52,7 +52,7 @@ ( ed ) dup >hced-tdhead le-l@ ( ed head ) intr-in-data@ or ( ed head' ) over >hced-tdhead le-l! ( ed ) - ( ed ) sync-edtds ( ) + ( ed ) push-edtds ( ) ; : remove-my-intr ( ed -- ) dup remove-intr free-edtds ;
@@ -80,13 +80,13 @@ intr-in-ed 0= if 0 USB_ERR_INV_OP exit then clear-usb-error ( ) process-hc-status ( ) - intr-in-ed dup sync-edtds ( ed ) + intr-in-ed dup pull-edtds ( ed ) ed-done? if ( ) intr-in-td error? if 0 ( actual ) else ( ) intr-in-td dup get-actual ( td actual ) - over >td-cbp l@ rot >td-pcbp l@ 2 pick dma-sync ( actual ) + over >td-cbp l@ rot >td-pcbp l@ 2 pick dma-pull ( actual ) then usb-error ( actual usberr ) intr-in-ed fixup-intr-in-data ( actual usberr ) @@ -118,7 +118,7 @@
\ Setup ED again intr-in-td >td-phys l@ intr-in-data@ or intr-in-ed >hced-tdhead le-l! - intr-in-ed dup sync-edtds + intr-in-ed dup push-edtds ed-unset-skip ;
Modified: dev/usb2/hcd/uhci/bulk.fth ============================================================================== --- dev/usb2/hcd/uhci/bulk.fth Tue Oct 11 23:59:39 2011 (r2590) +++ dev/usb2/hcd/uhci/bulk.fth Wed Oct 12 00:28:40 2011 (r2591) @@ -113,12 +113,12 @@ bulk-in-qh 0= if 0 USB_ERR_INV_OP exit then clear-usb-error process-hc-status - bulk-in-qh dup sync-qhtds ( bulk-in-qh ) + bulk-in-qh dup pull-qhtds ( bulk-in-qh ) qh-done? if ( ) bulk-in-actual ( actual usberr ) else ( ) bulk-in-qh dup >hcqh-elem le-l@ ( qh elem ) - 1 ms over sync-qhtds ( qh elem ) + 1 ms over pull-qhtds ( qh elem ) swap >hcqh-elem le-l@ = if \ No movement in the past ms bulk-in-actual ( actual usberr ) bulk-in-td bulk-in-qh >qh-#tds l@ fixup-bulk-in-data @@ -127,7 +127,7 @@ then then over if - bulk-in-td dup >td-buf l@ swap >td-pbuf l@ 2 pick dma-sync + bulk-in-td dup >td-buf l@ swap >td-pbuf l@ 2 pick dma-pull then ;
@@ -155,7 +155,7 @@
\ Setup QH again bulk-in-td >td-phys l@ bulk-in-qh >hcqh-elem le-l! - bulk-in-qh sync-qhtds + bulk-in-qh push-qhtds ;
: end-bulk-in ( -- ) @@ -188,7 +188,7 @@ 0 ( actual ) \ USB error else my-td dup my-#tds get-actual ( td actual ) - over >td-buf l@ rot >td-pbuf l@ 2 pick dma-sync ( actual ) + over >td-buf l@ rot >td-pbuf l@ 2 pick dma-pull ( actual ) then then
Modified: dev/usb2/hcd/uhci/control.fth ============================================================================== --- dev/usb2/hcd/uhci/control.fth Tue Oct 11 23:59:39 2011 (r2590) +++ dev/usb2/hcd/uhci/control.fth Wed Oct 12 00:28:40 2011 (r2591) @@ -125,7 +125,7 @@ 0 ( actual ) \ USB error else my-td >td-next l@ dup my-#tds get-actual ( td actual ) - over >td-buf l@ rot >td-pbuf l@ 2 pick dma-sync ( actual ) + over >td-buf l@ rot >td-pbuf l@ 2 pick dma-pull ( actual ) then then
Modified: dev/usb2/hcd/uhci/intr.fth ============================================================================== --- dev/usb2/hcd/uhci/intr.fth Tue Oct 11 23:59:39 2011 (r2590) +++ dev/usb2/hcd/uhci/intr.fth Wed Oct 12 00:28:40 2011 (r2591) @@ -76,11 +76,11 @@ intr-in-qh 0= if 0 USB_ERR_INV_OP exit then clear-usb-error process-hc-status - intr-in-qh dup sync-qhtds + intr-in-qh dup pull-qhtds qh-done? if intr-in-td intr-in-qh >qh-#tds l@ get-actual ( actual ) usb-error ( actual usberr ) - intr-in-td dup >td-buf l@ swap >td-pbuf l@ 2 pick dma-sync + intr-in-td dup >td-buf l@ swap >td-pbuf l@ 2 pick dma-pull intr-in-td intr-in-qh >qh-#tds l@ fixup-intr-in-data else 0 usb-error ( actual usberr ) @@ -109,7 +109,7 @@
\ Setup QH again intr-in-td >td-phys l@ intr-in-qh >hcqh-elem le-l! - intr-in-qh sync-qhtds + intr-in-qh push-qhtds ;
: end-intr-in ( -- )
Modified: dev/usb2/hcd/uhci/qhtd.fth ============================================================================== --- dev/usb2/hcd/uhci/qhtd.fth Tue Oct 11 23:59:39 2011 (r2590) +++ dev/usb2/hcd/uhci/qhtd.fth Wed Oct 12 00:28:40 2011 (r2591) @@ -230,8 +230,12 @@ aligned16-free-map-out ;
-: sync-qhtds ( qh -- ) - dup >qh-phys l@ over >qh-size l@ dma-sync +: push-qhtds ( qh -- ) + dup >qh-phys l@ over >qh-size l@ dma-push +; + +: pull-qhtds ( qh -- ) + dup >qh-phys l@ over >qh-size l@ dma-pull ;
: map-out-buf ( td -- ) @@ -299,7 +303,7 @@ process-hc-status usb-error if true else - dup sync-qhtds + dup pull-qhtds dup qh-done? ?dup 0= if 1 ms timeout 1- dup to timeout 0= @@ -310,7 +314,7 @@ ( qh ) dup qh-done? 0= if " Timeout" USB_ERR_TIMEOUT set-usb-error TERMINATE over >hcqh-elem le-l! \ Terminate QH - sync-qhtds + push-qhtds 1 ms else drop