Author: quozl Date: Wed Feb 6 07:48:16 2013 New Revision: 3536 URL: http://tracker.coreboot.org/trac/openfirmware/changeset/3536
Log: USB - add an interrupt lockout for the keyboard alarm handler, so that it is skipped if the non-interrupt context is in the middle of a bulk or interrupt pipe method. A fix for OLPC #12516. Actual cause still unknown.
Modified: dev/usb2/device/keyboard/request.fth dev/usb2/hcd/ehci/bulk.fth dev/usb2/hcd/ehci/intr.fth dev/usb2/hcd/hcd-call.fth dev/usb2/hcd/hcd.fth dev/usb2/hcd/ohci/bulk.fth dev/usb2/hcd/ohci/intr.fth dev/usb2/hcd/uhci/bulk.fth dev/usb2/hcd/uhci/intr.fth
Modified: dev/usb2/device/keyboard/request.fth ============================================================================== --- dev/usb2/device/keyboard/request.fth Tue Feb 5 05:01:23 2013 (r3535) +++ dev/usb2/device/keyboard/request.fth Wed Feb 6 07:48:16 2013 (r3536) @@ -77,6 +77,7 @@ : end-scan ( -- ) end-intr-in ;
: get-data? ( adr len -- actual ) + locked? if nip nip 0 exit then \ bulk or interrupt methods are active intr-in? if nip nip restart-intr-in exit then \ USB error; restart ?dup if ( adr len actual ) min tuck kbd-buf -rot move ( actual )
Modified: dev/usb2/hcd/ehci/bulk.fth ============================================================================== --- dev/usb2/hcd/ehci/bulk.fth Tue Feb 5 05:01:23 2013 (r3535) +++ dev/usb2/hcd/ehci/bulk.fth Wed Feb 6 07:48:16 2013 (r3536) @@ -421,6 +421,7 @@ ;
: bulk-in? ( -- actual usberr ) + lock bulk-in-ready? if ( usberr | buf actual 0 ) ?dup if ( usberr ) 0 swap ( actual usberr ) @@ -432,6 +433,7 @@ else ( ) 0 0 ( actual usberr ) then + unlock ;
: restart-bulk-in ( -- ) @@ -460,6 +462,7 @@ ; : bulk-in ( buf len pipe -- actual usberr ) debug? if ." bulk-in" cr then + lock dup to bulk-in-pipe process-bulk-args ?alloc-bulk-qhqtds to my-bulk-qtd to my-bulk-qh @@ -480,16 +483,19 @@ my-bulk-qtd map-out-bptrs ( actual usberr ) my-bulk-qh dup fixup-bulk-in-data ( actual usberr qh ) remove-qh ( actual usberr ) + unlock ;
0 instance value bulk-out-busy? : done-bulk-out ( -- error? ) + lock \ Process results 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 ) false to bulk-out-busy? ( usberr ) + unlock ; : start-bulk-out ( buf len pipe -- usberr ) bulk-out-busy? if ( buf len pipe ) @@ -497,6 +503,7 @@ then ( buf len pipe )
debug? if ." bulk-out" cr then + lock dup to bulk-out-pipe ( buf len pipe ) process-bulk-args ( ) ?alloc-bulk-qhqtds to my-bulk-qtd to my-bulk-qh ( ) @@ -507,6 +514,7 @@ TD_PID_OUT start-bulk-transaction ( ) true to bulk-out-busy? ( ) 0 ( usberr ) + unlock ; : bulk-out ( buf len pipe -- usberr ) start-bulk-out drop done-bulk-out
Modified: dev/usb2/hcd/ehci/intr.fth ============================================================================== --- dev/usb2/hcd/ehci/intr.fth Tue Feb 5 05:01:23 2013 (r3535) +++ dev/usb2/hcd/ehci/intr.fth Wed Feb 6 07:48:16 2013 (r3536) @@ -51,6 +51,7 @@ debug? if ." begin-intr-in" cr then intr-in-qh if 4drop exit then \ Already started
+ lock to intr-in-interval dup to intr-in-pipe process-intr-args @@ -63,10 +64,12 @@ \ Start intr in transaction intr-in-qh pt-intr fill-qh intr-in-qh my-speed intr-in-interval insert-intr-qh + unlock ;
: intr-in? ( -- actual usberr ) intr-in-qh 0= if 0 USB_ERR_INV_OP exit then ( ) + lock clear-usb-error ( ) \ Ironically, we can't use Interrupt-On-Completion for interrupt pipes, \ because when a bulk or control transaction is performed with IOC, the @@ -91,6 +94,7 @@ usb-error ( actual usberr ) intr-in-qh fixup-intr-in-data ( actual usberr ) then ( actual usberr ) + unlock ;
headers @@ -111,6 +115,7 @@ : restart-intr-in ( -- ) intr-in-qh 0= if exit then
+ lock \ Setup qTD again intr-in-qtd restart-intr-in-qtd
@@ -119,15 +124,18 @@ 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 push-qhqtds + unlock ;
: end-intr-in ( -- ) debug? if ." end-intr-in" cr then intr-in-qh 0= if exit then + lock intr-in-qh dup fixup-intr-in-data intr-in-qtd map-out-bptrs dup remove-intr-qh free-qh 0 to intr-in-qh 0 to intr-in-qtd + unlock ;
headers
Modified: dev/usb2/hcd/hcd-call.fth ============================================================================== --- dev/usb2/hcd/hcd-call.fth Tue Feb 5 05:01:23 2013 (r3535) +++ dev/usb2/hcd/hcd-call.fth Wed Feb 6 07:48:16 2013 (r3536) @@ -10,6 +10,10 @@ : dma-alloc ( size -- virt ) " dma-alloc" $call-parent ; : dma-free ( virt size -- ) " dma-free" $call-parent ;
+: locked? ( -- flag ) + " locked?" $call-parent +; + \ Probing support : set-target ( device -- ) " set-target" $call-parent
Modified: dev/usb2/hcd/hcd.fth ============================================================================== --- dev/usb2/hcd/hcd.fth Tue Feb 5 05:01:23 2013 (r3535) +++ dev/usb2/hcd/hcd.fth Wed Feb 6 07:48:16 2013 (r3536) @@ -54,6 +54,10 @@ then ;
+0 value locked? \ Interrupt lockout for USB keyboard get-data? +: lock ( -- ) true to locked? ; +: unlock ( -- ) false to locked? ; + \ --------------------------------------------------------------------------- \ Common routines \ ---------------------------------------------------------------------------
Modified: dev/usb2/hcd/ohci/bulk.fth ============================================================================== --- dev/usb2/hcd/ohci/bulk.fth Tue Feb 5 05:01:23 2013 (r3535) +++ dev/usb2/hcd/ohci/bulk.fth Wed Feb 6 07:48:16 2013 (r3536) @@ -124,6 +124,7 @@
: bulk-in? ( -- actual usberr ) bulk-in-ed 0= if 0 USB_ERR_INV_OP exit then + lock clear-usb-error ( ) process-hc-status ( ) bulk-in-ed dup pull-edtds ( ed ) @@ -139,6 +140,7 @@ else 0 usb-error ( actual usberr ) then + unlock ;
headers @@ -157,6 +159,7 @@ external : restart-bulk-in ( -- ) debug? if ." restart-bulk-in" cr then + lock bulk-in-ed 0= if exit then bulk-in-ed ed-set-skip
@@ -168,18 +171,22 @@ bulk-in-ed dup push-edtds ed-unset-skip enable-bulk + unlock ;
: end-bulk-in ( -- ) debug? if ." end-bulk-in" cr then + lock bulk-in-ed 0= if exit then bulk-in-td map-out-cbp bulk-in-ed remove-my-bulk 0 to bulk-in-ed 0 to bulk-in-td + unlock ;
: bulk-in ( buf len pipe -- actual usberr ) debug? if ." bulk-in" cr then + lock dup to bulk-in-pipe bulk-in-timeout process-bulk-args ( ) alloc-bulk-edtds to my-td to my-ed ( ) @@ -206,10 +213,12 @@ my-td map-out-cbp ( actual usberr ed ) my-ed dup fixup-bulk-in-data ( actual usberr ed ) remove-my-bulk ( actual usberr ) + unlock ;
: bulk-out ( buf len pipe -- usberr ) debug? if ." bulk-out" cr then + lock dup to bulk-out-pipe bulk-out-timeout process-bulk-args alloc-bulk-edtds to my-td to my-ed @@ -227,6 +236,7 @@ my-td map-out-cbp my-ed dup fixup-bulk-out-data remove-my-bulk + unlock ;
headers
Modified: dev/usb2/hcd/ohci/intr.fth ============================================================================== --- dev/usb2/hcd/ohci/intr.fth Tue Feb 5 05:01:23 2013 (r3535) +++ dev/usb2/hcd/ohci/intr.fth Wed Feb 6 07:48:16 2013 (r3536) @@ -61,6 +61,7 @@ : begin-intr-in ( buf len pipe interval -- ) debug? if ." begin-intr-in" cr then intr-in-ed if 4drop exit then \ Already started + lock #intr-in++
to intr-in-interval @@ -74,10 +75,12 @@ \ Start intr transaction intr-in-ed dup fill-intr-in-ed insert-in-intr + unlock ;
: intr-in? ( -- actual usberr ) intr-in-ed 0= if 0 USB_ERR_INV_OP exit then + lock clear-usb-error ( ) process-hc-status ( ) intr-in-ed dup pull-edtds ( ed ) @@ -93,6 +96,7 @@ else 0 usb-error ( actual usberr ) then + unlock ;
headers @@ -111,6 +115,7 @@ external : restart-intr-in ( -- ) intr-in-ed 0= if exit then + lock intr-in-ed ed-set-skip
\ Setup TD again @@ -120,15 +125,18 @@ intr-in-td >td-phys l@ intr-in-data@ or intr-in-ed >hced-tdhead le-l! intr-in-ed dup push-edtds ed-unset-skip + unlock ;
: end-intr-in ( -- ) debug? if ." end-intr-in" cr then intr-in-ed 0= if exit then + lock #intr-in-- intr-in-td map-out-cbp intr-in-ed remove-my-intr 0 to intr-in-ed 0 to intr-in-td + unlock ;
headers
Modified: dev/usb2/hcd/uhci/bulk.fth ============================================================================== --- dev/usb2/hcd/uhci/bulk.fth Tue Feb 5 05:01:23 2013 (r3535) +++ dev/usb2/hcd/uhci/bulk.fth Wed Feb 6 07:48:16 2013 (r3536) @@ -111,6 +111,7 @@
: bulk-in? ( -- actual usberr ) bulk-in-qh 0= if 0 USB_ERR_INV_OP exit then + lock clear-usb-error process-hc-status bulk-in-qh dup pull-qhtds ( bulk-in-qh ) @@ -129,6 +130,7 @@ over if bulk-in-td dup >td-buf l@ swap >td-pbuf l@ 2 pick dma-pull then + unlock ;
headers @@ -170,6 +172,7 @@
: bulk-in ( buf len pipe -- actual usberr ) debug? if ." bulk-in" cr then + lock dup to bulk-in-pipe bulk-in-timeout process-bulk-args alloc-bulk-qhtds to my-td to my-qh @@ -197,10 +200,12 @@ my-td dup map-out-buf ( actual usberr qh td ) my-#tds fixup-bulk-in-data ( actual usberr qh ) dup remove-qh free-qhtds ( actual usberr ) + unlock ;
: bulk-out ( buf len pipe -- usberr ) debug? if ." bulk-out" cr then + lock dup to bulk-out-pipe bulk-out-timeout process-bulk-args alloc-bulk-qhtds to my-td to my-qh @@ -219,6 +224,7 @@ my-td dup map-out-buf ( actual usberr qh td ) my-#tds fixup-bulk-out-data ( actual usberr qh ) dup remove-qh free-qhtds ( actual usberr ) + unlock ;
headers
Modified: dev/usb2/hcd/uhci/intr.fth ============================================================================== --- dev/usb2/hcd/uhci/intr.fth Tue Feb 5 05:01:23 2013 (r3535) +++ dev/usb2/hcd/uhci/intr.fth Wed Feb 6 07:48:16 2013 (r3536) @@ -60,6 +60,7 @@ debug? if ." begin-intr-in" cr then intr-in-qh if 4drop exit then \ Already started
+ lock to intr-in-interval dup to intr-in-pipe intr-in-timeout process-intr-args @@ -70,10 +71,12 @@
\ Start intr in transaction intr-in-qh intr-in-interval insert-intr-qh + unlock ;
: intr-in? ( -- actual usberr ) intr-in-qh 0= if 0 USB_ERR_INV_OP exit then + lock clear-usb-error process-hc-status intr-in-qh dup pull-qhtds @@ -85,6 +88,7 @@ else 0 usb-error ( actual usberr ) then + unlock ;
headers @@ -104,22 +108,26 @@ debug? if ." restart-intr-in" cr then intr-in-qh 0= if exit then
+ lock \ Setup TD again intr-in-td restart-intr-in-td
\ Setup QH again intr-in-td >td-phys l@ intr-in-qh >hcqh-elem le-l! intr-in-qh push-qhtds + unlock ;
: end-intr-in ( -- ) debug? if ." end-intr-in" cr then intr-in-qh 0= if exit then
+ lock intr-in-td intr-in-qh >qh-#tds l@ fixup-intr-in-data intr-in-td map-out-buf intr-in-qh dup remove-qh free-qhtds 0 to intr-in-qh 0 to intr-in-td + unlock ;
headers