Author: wmb Date: 2010-01-09 01:20:44 +0100 (Sat, 09 Jan 2010) New Revision: 1654
Modified: dev/usb2/device/net/ethernet.fth dev/usb2/device/net/pegasus.fth dev/usb2/device/storage/scsi.fth dev/usb2/hcd/control.fth dev/usb2/hcd/dev-info.fth dev/usb2/hcd/device.fth dev/usb2/hcd/ehci/probe.fth dev/usb2/hcd/hcd.fth dev/usb2/hcd/ohci/probe.fth dev/usb2/hcd/uhci/probe.fth Log: OLPC trac 9969 - USB is working better after resume. Existing device nodes are reused to avoid excessive memory consumption. In the usual case where the devices are the same before and after S3, no additional memory is consumed. The only devices that are known to continue working after S3 are still Ethernet and mass storage.
Modified: dev/usb2/device/net/ethernet.fth =================================================================== --- dev/usb2/device/net/ethernet.fth 2010-01-08 23:36:37 UTC (rev 1653) +++ dev/usb2/device/net/ethernet.fth 2010-01-09 00:20:44 UTC (rev 1654) @@ -211,10 +211,16 @@ : open ( -- ok? ) my-args " debug" $= if debug-on then device set-target + configuration set-config if + ." Failed to set configuration" cr + false exit + then + opencount @ 0= if + " reset?" $call-parent if init-nic then + first-open? if false to first-open? - init-nic mac-adr$ encode-bytes " local-mac-address" property ( ) ?make-mac-address-property then
Modified: dev/usb2/device/net/pegasus.fth =================================================================== --- dev/usb2/device/net/pegasus.fth 2010-01-08 23:36:37 UTC (rev 1653) +++ dev/usb2/device/net/pegasus.fth 2010-01-09 00:20:44 UTC (rev 1654) @@ -121,7 +121,6 @@ : pg-init-nic ( -- ) true to length-header? init-buf - 1 set-config error? pg-get-mac-address 2drop pg-init-mac setup-pegasus-II
Modified: dev/usb2/device/storage/scsi.fth =================================================================== --- dev/usb2/device/storage/scsi.fth 2010-01-08 23:36:37 UTC (rev 1653) +++ dev/usb2/device/storage/scsi.fth 2010-01-09 00:20:44 UTC (rev 1654) @@ -183,6 +183,9 @@ : set-address ( lun -- ) 0 max max-lun min to lun device set-target + configuration set-config if + ." USB storage scsi layer: Failed to set configuration" cr + then ; : set-timeout ( n -- ) bulk-timeout max set-bulk-in-timeout ;
Modified: dev/usb2/hcd/control.fth =================================================================== --- dev/usb2/hcd/control.fth 2010-01-08 23:36:37 UTC (rev 1653) +++ dev/usb2/hcd/control.fth 2010-01-09 00:20:44 UTC (rev 1654) @@ -122,6 +122,11 @@ encoded$>ascii$ ( ) ;
+\ Returns true the first time it is called for a given target device +\ after a reset of the USB subsystem. Used for reinitializing hardware. + +: reset? ( -- flag ) target di-reset? ; + headers
\ LICENSE_BEGIN
Modified: dev/usb2/hcd/dev-info.fth =================================================================== --- dev/usb2/hcd/dev-info.fth 2010-01-08 23:36:37 UTC (rev 1653) +++ dev/usb2/hcd/dev-info.fth 2010-01-09 00:20:44 UTC (rev 1654) @@ -22,7 +22,7 @@ 1 field >di-speed \ Device speed 1 field >di-hub \ Hub address (EHCI only) 1 field >di-port \ Port number (EHCI only) - 1+ \ Padding for word alignment + 1 field >di-reset \ rest flag - 0 initially or after a resume, then 1 /di-ep-struct #max-endpoint * field >di-ep \ Endpoint structure constant /di-entry @@ -41,6 +41,11 @@ : di-hub@ ( idx -- hub ) 'di >di-hub c@ ; : di-port! ( port idx -- ) 'di >di-port c! ; : di-port@ ( idx -- port ) 'di >di-port c@ ; +: di-reset? ( idx -- flag ) + 'di >di-reset ( adr ) + dup c@ 0= ( adr reset? ) + 1 rot c! ( reset? ) +;
: 'di-maxpayload ( pipe idx -- adr ) 'di-ep >di-ep-maxpayload ; : di-maxpayload! ( len pipe idx -- ) 'di-maxpayload w! ; @@ -63,9 +68,9 @@ di 0= if \ allocate and initialize the device descriptors /di alloc-mem to di - di /di erase - /pipe0 0 0 di-maxpayload! \ Default max payload then + di /di erase + /pipe0 0 0 di-maxpayload! \ Default max payload ;
: init-struct ( -- )
Modified: dev/usb2/hcd/device.fth =================================================================== --- dev/usb2/hcd/device.fth 2010-01-08 23:36:37 UTC (rev 1653) +++ dev/usb2/hcd/device.fth 2010-01-09 00:20:44 UTC (rev 1654) @@ -238,8 +238,61 @@ 0 0 2swap str-property ;
+: be-l! ( n adr -- ) + >r lbsplit r@ c! r@ 1+ c! r@ 2+ c! r> 3 + c! +; + +: reuse-node ( dev intf port phandle -- ) + nip nip ( dev phandle ) +[ifdef] notdef + \ This is the kosher way to do it ... + push-package ( dev ) + 2drop ( dev ) + encode-int ( adr len ) + " assigned-address" property ( ) + pop-package ( ) +[else] ( dev phandle ) + \ But this way doesn't leak memory + " assigned-address" rot get-package-property if ( dev ) + drop ( ) + else ( dev adr len ) + drop be-l! ( ) + then ( ) +[then] +; +: reuse-old-node? ( dev intf port -- reused? ) + my-self ihandle>phandle child ( dev intf port phandle ) + begin ?dup while ( dev intf port phandle ) + " reg" 2 pick get-package-property 0= if ( dev intf port phandle adr len ) + decode-int ( dev intf port phandle adr len' port1 ) + 4 pick = if ( dev intf port phandle adr len ) + decode-int nip nip ( dev intf port phandle intf1 ) + 3 pick = if ( dev intf port phandle ) + reuse-node ( ) + true exit ( -- true ) + then ( dev intf port phandle ) + else ( dev intf port phandle adr len ) + 2drop ( dev intf port phandle ) + then ( dev intf port phandle ) + then ( dev intf port phandle ) + peer ( dev intf port phandle' ) + repeat ( dev intf port ) + 3drop false +; + : (make-device-node) ( dev port intf -- ) - swap dup >r encode-unit " " 2swap new-device set-args ( dev ) ( R: port ) + swap ( dev intf port ) + 3dup reuse-old-node? if ( dev intf port ) + 3drop exit + else + \ As a possible improvement, the old child node could be linked to + \ a retained list for possible reuse later +\ We don't do this because it can remove nodes we just created. +\ say we create keyboard@3,0 then we try to create hid@3,1 +\ rm-obsolete-children will delete keyboard@3,0 +\ dup rm-obsolete-children ( dev intf port ) + then + dup >r encode-unit " " 2swap new-device set-args ( dev ) ( R: port ) dup dup di-speed@ swap r> make-dev-property-hook ( dev ) make-common-properties \ Make non-descriptor based properties make-descriptor-properties \ Make descriptor based properties
Modified: dev/usb2/hcd/ehci/probe.fth =================================================================== --- dev/usb2/hcd/ehci/probe.fth 2010-01-08 23:36:37 UTC (rev 1653) +++ dev/usb2/hcd/ehci/probe.fth 2010-01-09 00:20:44 UTC (rev 1654) @@ -126,7 +126,7 @@
#ports 0 ?do \ For each port i portsc@ 2 and if \ Connection changed - i rm-obsolete-children \ Remove obsolete device nodes +\ i rm-obsolete-children \ Remove obsolete device nodes i probe-root-hub-port \ Probe it then loop
Modified: dev/usb2/hcd/hcd.fth =================================================================== --- dev/usb2/hcd/hcd.fth 2010-01-08 23:36:37 UTC (rev 1653) +++ dev/usb2/hcd/hcd.fth 2010-01-09 00:20:44 UTC (rev 1654) @@ -124,9 +124,9 @@
headers
-: rm-obsolete-children ( port -- ) - " rm-usb-children" $find if execute else 3drop then -; +\ : rm-obsolete-children ( port -- ) +\ " rm-usb-children" $find if execute else 3drop then +\ ;
: parse-my-args ( -- ) my-args
Modified: dev/usb2/hcd/ohci/probe.fth =================================================================== --- dev/usb2/hcd/ohci/probe.fth 2010-01-08 23:36:37 UTC (rev 1653) +++ dev/usb2/hcd/ohci/probe.fth 2010-01-09 00:20:44 UTC (rev 1654) @@ -94,7 +94,7 @@ alloc-pkt-buf #ports 0 ?do i hc-rh-psta@ 3.0000 and if - i rm-obsolete-children \ Remove obsolete device nodes +\ i rm-obsolete-children \ Remove obsolete device nodes i ['] probe-root-hub-port catch if drop ." Failed to probe root port " i u. cr then
Modified: dev/usb2/hcd/uhci/probe.fth =================================================================== --- dev/usb2/hcd/uhci/probe.fth 2010-01-08 23:36:37 UTC (rev 1653) +++ dev/usb2/hcd/uhci/probe.fth 2010-01-09 00:20:44 UTC (rev 1654) @@ -41,7 +41,7 @@ alloc-pkt-buf 2 0 do i portsc@ h# a and if - i rm-obsolete-children \ Remove obsolete device nodes +\ i rm-obsolete-children \ Remove obsolete device nodes i ['] probe-root-hub-port catch if drop ." Failed to probe root port " i .d cr then
openfirmware@openfirmware.info