[openfirmware] [commit] r2152 - in dev/usb2: . device/hub hcd hcd/ehci hcd/ohci hcd/uhci

repository service svn at openfirmware.info
Thu Jan 27 00:40:26 CET 2011


Author: wmb
Date: Thu Jan 27 00:40:25 2011
New Revision: 2152
URL: http://tracker.coreboot.org/trac/openfirmware/changeset/2152

Log:
USB - extensive surgery on USB probing code so hot-plug works behind hubs.

Modified:
   dev/usb2/device/hub/hub.fth
   dev/usb2/hcd/dev-info.fth
   dev/usb2/hcd/device.fth
   dev/usb2/hcd/ehci/control.fth
   dev/usb2/hcd/ehci/loadpkg.fth
   dev/usb2/hcd/ehci/probe.fth
   dev/usb2/hcd/ehci/probehub.fth
   dev/usb2/hcd/hcd-call.fth
   dev/usb2/hcd/ohci/probe.fth
   dev/usb2/hcd/probehub.fth
   dev/usb2/hcd/uhci/loadpkg.fth
   dev/usb2/hcd/uhci/probe.fth
   dev/usb2/hcd/uhci/uhci.fth
   dev/usb2/pkt-data.fth
   dev/usb2/pkt-func.fth

Modified: dev/usb2/device/hub/hub.fth
==============================================================================
--- dev/usb2/device/hub/hub.fth	Wed Jan 26 20:01:33 2011	(r2151)
+++ dev/usb2/device/hub/hub.fth	Thu Jan 27 00:40:25 2011	(r2152)
@@ -33,14 +33,26 @@
    then
    decode-int nip nip
 ;
+: ?make-hub20-dev  ( hub-dev -- hub-dev )
+   is-hub20?  if                                ( hub-dev )
+      " hub20-dev" get-my-property   if         ( hub-dev )
+         dup encode-int " hub20-dev" property   ( hub-dev )
+      else   \ Property already exists          ( hub-dev adr len )
+         2drop                                  ( hub-dev )
+      then                                      ( hub-dev )
+   then                                         ( hub-dev )
+;
 : probe-hub  ( -- )
    ['] hub-id catch 0=  if
-      is-hub20?  if
-         dup encode-int " hub20-dev" property
-      then
+      ?make-hub20-dev
       probe-hub-xt execute
    then
 ;
+: reprobe-hub  ( -- )
+   ['] hub-id catch 0=  if
+      reprobe-hub-xt execute
+   then
+;
 
 probe-hub
 

Modified: dev/usb2/hcd/dev-info.fth
==============================================================================
--- dev/usb2/hcd/dev-info.fth	Wed Jan 26 20:01:33 2011	(r2151)
+++ dev/usb2/hcd/dev-info.fth	Thu Jan 27 00:40:25 2011	(r2152)
@@ -62,10 +62,11 @@
 : di-in-data-toggle   ( pipe idx -- )  2dup di-in-data@  1 xor -rot di-in-data!   ;
 : di-out-data-toggle  ( pipe idx -- )  2dup di-out-data@ 1 xor -rot di-out-data!  ;
 
-: ok-to-add-device?  ( -- flag )  cur-dev 1+ #max-dev <  ;
-: new-address  ( -- dev )
+: next-device#  ( -- true | dev false )
+   cur-dev 1+ #max-dev >=  if  true exit  then
    cur-dev 1+ dup to cur-dev  
    /pipe0 0 cur-dev di-maxpayload!
+   false
 ;
 
 : init-di  ( -- )

Modified: dev/usb2/hcd/device.fth
==============================================================================
--- dev/usb2/hcd/device.fth	Wed Jan 26 20:01:33 2011	(r2151)
+++ dev/usb2/hcd/device.fth	Thu Jan 27 00:40:25 2011	(r2152)
@@ -10,7 +10,6 @@
 \ Buffers for descriptor manipulation
 0 value cfg-desc-buf			\ Configuration Descriptor
 0 value dev-desc-buf			\ Device Descriptor
-0 value gen-desc-buf			\ Any Descriptor
 0 value d$-desc-buf			\ Device String Descriptor
 0 value v$-desc-buf			\ Vendor String Descriptor
 0 value s$-desc-buf			\ Serial Number String Descriptor
@@ -25,7 +24,6 @@
    cfg-desc-buf 0=  if
       /cfg alloc-mem dup to cfg-desc-buf /cfg erase
       /cfg alloc-mem dup to dev-desc-buf /cfg erase
-      /cfg alloc-mem dup to gen-desc-buf /cfg erase
       /str alloc-mem dup to d$-desc-buf /str erase
       /str alloc-mem dup to v$-desc-buf /str erase
       /str alloc-mem dup to s$-desc-buf /str erase
@@ -34,14 +32,27 @@
 : free-pkt-buf  ( -- )
    cfg-desc-buf ?dup  if  /cfg free-mem  0 to cfg-desc-buf  then
    dev-desc-buf ?dup  if  /cfg free-mem  0 to dev-desc-buf  then
-   gen-desc-buf ?dup  if  /cfg free-mem  0 to gen-desc-buf  then
    d$-desc-buf  ?dup  if  /str free-mem  0 to d$-desc-buf   then
    v$-desc-buf  ?dup  if  /str free-mem  0 to v$-desc-buf   then
    s$-desc-buf  ?dup  if  /str free-mem  0 to s$-desc-buf   then
 ;
 
+: dev-desc@  ( index -- byte )  dev-desc-buf + c@  ;
+: get-class  ( -- class subclass protocol )
+   4 dev-desc@ ?dup  if			( class )
+      \ Class is in device descriptor
+      true to class-in-dev?			( class )
+      5 dev-desc@  6 dev-desc@			( class subclass protocol )
+   else						( )
+      \ Class is in interface descriptor
+      false to class-in-dev?			( )
+      cfg-desc-buf my-address find-intf-desc	( intf-adr )
+      >r  r@ 5 + c@  r@ 6 + c@   r> 7 + c@	( class subclass protocol )
+   then
+;
+
 : make-class-properties  ( -- )
-   dev-desc-buf cfg-desc-buf my-address get-class	( class subclass protocol )
+   get-class  ( class subclass protocol )
    " protocol" int-property
    " subclass" int-property
    " class"    int-property
@@ -83,8 +94,12 @@
    device-name
 ;
 
+: get-vid  ( adr -- vendor product rev )
+   dev-desc-buf 8 + le-w@   dev-desc-buf d# 10 + le-w@  dev-desc-buf c + le-w@
+;
+
 : make-vendor-properties  ( -- )
-   dev-desc-buf get-vid			( vendor product rev )
+   get-vid			( vendor product rev )
    " release"   int-property
    " device-id" int-property
    " vendor-id" int-property
@@ -256,6 +271,18 @@
    >r lbsplit r@ c!  r@ 1+ c!  r@ 2+ c!  r> 3 + c!
 ;
 
+: probe-hub-node  ( phandle -- )
+   >r                                       ( r: phandle )
+   " probe-hub" r@ find-method  if          ( xt r: phandle )
+      r@ push-package                       ( xt r: phandle )
+      " " new-instance                      ( xt r: phandle )
+      set-default-unit                      ( xt r: phandle )
+      execute                               ( r: phandle )
+      destroy-instance                      ( r: phandle )
+      pop-package                           ( r: phandle )
+   then                                     ( r: phandle )
+   r> drop
+;
 : reuse-node  ( dev intf port phandle -- )
    >r drop			  ( dev intf r: phandle )
 
@@ -269,18 +296,8 @@
       drop be-l!                            ( r: phandle )
    then                                     ( r: phandle )
 
-   " probe-hub" r@ find-method  if          ( xt r: phandle )
-      r@ push-package                       ( xt r: phandle )
-      " " new-instance                      ( xt r: phandle )
-      set-default-unit                      ( xt r: phandle )
-      execute                               ( r: phandle )
-      destroy-instance                      ( r: phandle )
-      pop-package                           ( r: phandle )
-   then                                     ( r: phandle )
-
-   r> drop
+   r> probe-hub-node
 ;
-
 : id-match?  ( dev intf port phandle -- dev intf port phandle flag? )
    " vendor-id" 2 pick get-package-property  if  false exit  then
    decode-int nip nip   >r     ( dev intf port phandle r: vid )
@@ -288,7 +305,7 @@
    decode-int nip nip   >r     ( dev intf port phandle r: vid did )
    " release" 2 pick get-package-property  if  r> r> 2drop  false exit  then
    decode-int nip nip   >r     ( dev intf port phandle r: vid did rev )
-   dev-desc-buf get-vid        ( dev intf port phandle  vid1 did1 rev1 r: vid did rev )
+   get-vid                     ( dev intf port phandle  vid1 did1 rev1 r: vid did rev )
    r> = -rot  r> = -rot  r> =  and and
 ;
 
@@ -335,42 +352,126 @@
 ;
 
 \ Get all the descriptors we need in making properties now because target is
-\ questionable in the child's context.
+\ questionable in the child's context.  The descriptor buffers are not instance
+\ data, so they can be accessed by code that is defined in the root hub node
+\ but executing in a subordinate hub node context or a child node context.
 
 h# 409 constant language  			\ Unicode id
+\ Executed in root hub node context
 : get-string ( lang idx adr -- actual )
    over 0=  if  3drop  0 exit  then		\ No string index
    -rot get-str-desc
 ;
+
+\ Executed in root hub node context
 : get-str-descriptors  ( -- )
    language					( lang )
    dup dev-desc-buf d# 14 + c@ v$-desc-buf get-string to /v$-desc-buf
    dup dev-desc-buf d# 15 + c@ d$-desc-buf get-string to /d$-desc-buf
        dev-desc-buf d# 16 + c@ s$-desc-buf get-string to /s$-desc-buf
 ;
-: refresh-desc-bufs  ( -- )
+
+\ Executed in root hub node context
+: refresh-desc-bufs  ( dev -- )
+   set-target
    dev-desc-buf 12 get-dev-desc to /dev-desc-buf		\ Refresh dev-desc-buf
    cfg-desc-buf  0 get-cfg-desc to /cfg-desc-buf		\ Refresh cfg-desc-buf
    get-str-descriptors
 ;
 
-: set-maxpayload  ( dev -- )
-   dev-desc-buf /pipe0 get-dev-desc  if
-      dev-desc-buf 7 + c@ 0 rot di-maxpayload!
-   else
-      drop
-   then
+\ Executed in root hub node context
+: get-initial-descriptors  ( dev -- )
+   dev-desc-buf /pipe0 get-dev-desc  if		( dev )
+      dev-desc-buf 7 + c@ 0 rot di-maxpayload!	( )
+   else						( dev )
+      drop					( )
+   then						( )
+   cfg-desc-buf 0 get-cfg-desc to /cfg-desc-buf	( )
 ;
 
+\ Executed in hub node context (root hub or subordinate hub) - creates new child nodes via (make-device-node)
 : make-device-node  ( port dev -- )
-   dup set-maxpayload			( port dev )
-   cfg-desc-buf 0 get-cfg-desc dup to /cfg-desc-buf
-   0=  if  2drop  exit  then
-   cfg-desc-buf 4 + c@ 0  ?do		( port dev )
-      dup set-target			( port dev )		\ Refresh target
-      refresh-desc-bufs			( port dev )
-      2dup swap i (make-device-node)	( port dev )
-   loop  2drop				( )
+   dup " get-initial-descriptors" my-self $call-method	( port dev )
+   /cfg-desc-buf 0=  if  2drop  exit  then		( port dev )
+   cfg-desc-buf 4 + c@ 0  ?do				( port dev )
+      dup " refresh-desc-bufs" my-self $call-method	( port dev )
+      2dup swap i (make-device-node)			( port dev )
+   loop  2drop						( )
+;
+
+\ See hcd/ehci/probehub.fth for information about hub20-dev and hub20-port
+
+: get-hub20-dev  ( -- hub-dev )
+   " hub20-dev" get-inherited-property 0=  if   ( value$ )
+      decode-int nip nip                        ( hub-dev )
+   else                                         ( )
+      1                                         ( hub-dev )
+   then                                         ( hub-dev )
+;
+
+: get-hub20-port  ( port -- port' )
+   " hub20-port" get-inherited-property 0=  if  ( port value$ )
+      rot drop				        ( value$ )
+      decode-int nip nip                        ( port' )
+   then                                         ( port )
+;
+
+\ Executed in the root hub node context
+: setup-new-node  ( port speed hub-port hub-dev -- true | port dev xt false )
+  \ Allocate device number
+   next-device#  if  2drop  exit  then	( port speed hub-port hub-dev dev )
+
+   tuck di-hub!				( port speed hub-port dev )
+   tuck di-port!			( port speed dev )
+   tuck di-speed!			( port dev )
+
+   0 set-target				( port dev )	\ Address it as device 0
+   dup set-address  if			( port dev )	\ Assign it usb addr dev
+      ." Retrying with a delay" cr
+      over reset-port  d# 5000 ms
+      dup set-address  if		( port dev )	\ Assign it usb addr dev
+         \ Recycle device number?
+         2drop false exit		( -- false )
+      then				( port dev )
+   then					( port dev )
+
+   dup set-target			( port dev )	\ Address it as device dev
+   ['] make-device-node	 true		( port dev xt )
+;
+
+\ Begins execution in a (root or subordinate) hub node context, creates an instance record
+\ for the subordinate hub node "phandle", switches to that instance context, executes
+\ "reprobe-hub" in that context, destroys the instance, and returns to the original context.
+: reprobe-hub-node  ( phandle -- )
+   >r                                       ( r: phandle )
+   " reprobe-hub" r@ find-method  if        ( xt r: phandle )
+      r@ push-package                       ( xt r: phandle )
+      " " new-instance                      ( xt r: phandle )
+      set-default-unit                      ( xt r: phandle )
+      execute                               ( r: phandle )
+      destroy-instance                      ( r: phandle )
+      pop-package                           ( r: phandle )
+   then                                     ( r: phandle )
+   r> drop
+;
+
+\ Returns true if there is a child hub node associated with port
+: port-is-hub?  ( port -- false | phandle true )
+   my-self ihandle>phandle child                       ( port phandle )
+   begin  ?dup  while                                  ( port phandle )
+      " name" 2 pick get-package-property 0=  if       ( port phandle adr len )
+         1-  " hub" $=  if                             ( port phandle )
+            " reg" 2 pick get-package-property 0=  if  ( port phandle adr len )
+               decode-int nip nip                      ( port phandle port1 )
+               2 pick =  if                            ( port phandle )
+                  nip true exit                        ( -- phandle true )
+               then                                    ( port phandle )
+            then                                       ( port phandle )
+         then                                          ( port phandle )
+      then                                             ( port phandle )
+      peer                                             ( port phandle' )
+   repeat                                              ( port )
+   drop false                                          ( false )
 ;
 
 headers

Modified: dev/usb2/hcd/ehci/control.fth
==============================================================================
--- dev/usb2/hcd/ehci/control.fth	Wed Jan 26 20:01:33 2011	(r2151)
+++ dev/usb2/hcd/ehci/control.fth	Thu Jan 27 00:40:25 2011	(r2152)
@@ -65,7 +65,7 @@
       swap  case				( qh endp-char pipetype )
          pt-ctrl  of  QH_MULT1  d#  64  endof	( qh endp-char endp-cap /max )
          pt-bulk  of  QH_MULT1  d# 512  endof	( qh endp-char endp-cap /max )
-         ( default )  r> QH_MULT1  my-maxpayload r>
+         ( default )  >r QH_MULT1  my-maxpayload r>
 						( qh endp-char endp-cap /max )
       endcase
       d# 16 << rot or swap			( qh endp-char endp-cap )

Modified: dev/usb2/hcd/ehci/loadpkg.fth
==============================================================================
--- dev/usb2/hcd/ehci/loadpkg.fth	Wed Jan 26 20:01:33 2011	(r2151)
+++ dev/usb2/hcd/ehci/loadpkg.fth	Thu Jan 27 00:40:25 2011	(r2152)
@@ -21,8 +21,6 @@
 fload ${BP}/dev/usb2/device/vendor.fth		\ Supported vendor/product tables
 fload ${BP}/dev/usb2/hcd/fcode.fth		\ Load fcode driver for child
 fload ${BP}/dev/usb2/hcd/device.fth		\ Make child node & its properties
-fload ${BP}/dev/usb2/hcd/ehci/probe.fth		\ Probe root hub
 fload ${BP}/dev/usb2/hcd/ehci/probehub.fth	\ USB 2.0 hub specific stuff
-fload ${BP}/dev/usb2/hcd/probehub.fth		\ Probe usb hub
-
-
+fload ${BP}/dev/usb2/hcd/ehci/probe.fth		\ Probe root hub
+fload ${BP}/dev/usb2/hcd/probehub.fth		\ Generic hub probing

Modified: dev/usb2/hcd/ehci/probe.fth
==============================================================================
--- dev/usb2/hcd/ehci/probe.fth	Wed Jan 26 20:01:33 2011	(r2151)
+++ dev/usb2/hcd/ehci/probe.fth	Thu Jan 27 00:40:25 2011	(r2152)
@@ -5,29 +5,18 @@
 headers
 
 : make-root-hub-node  ( port -- )
-   ok-to-add-device? 0=  if  drop exit  then		\ Can't add another device
-
-   0 set-target				( port )	\ Address it as device 0
-
+   \ Some devices (e.g. Lexar USB-to-SD) fail unless you get the cfg desc from device 0 first
+   0 set-target	\ First address it as device 0	( port )
    speed-high 0 di-speed!     \ Use high speed for getting the device descriptor
-   \ Some devices (e.g. Lexar USB-to-SD) don't work unless you do this first
-   dev-desc-buf h# 40 get-cfg-desc drop
+   dev-desc-buf h# 40 get-cfg-desc drop		( port )
 
-   new-address				( port dev )
-   speed-high over di-speed!		( port dev )
+   speed-high					( port speed )
 
-   0 set-target				( port dev )	\ Address it as device 0
+   \ hub-port and hub-dev route USB 1.1 transactions through USB 2.0 hubs
+   over get-hub20-port  get-hub20-dev		( port speed hub-port hub-dev )
 
-   dup set-address  if			( port dev )	\ Assign it usb addr dev
-      ." Retrying with a delay" cr
-      over reset-port  d# 5000 ms
-      dup set-address  if		( port dev )	\ Assign it usb addr dev
-         2drop exit
-      then
-   then ( port dev )
-
-   dup set-target			( port dev )	\ Address it as device dev
-   make-device-node			( )
+   \ Execute setup-new-node in root context and make-device-node in hub node context
+   setup-new-node  if  execute  then	( )
 ;
 
 0 instance value probe-error?  \ Back channel to selftest
@@ -43,7 +32,7 @@
 	 dup disown-port			\ Disown the port
       else					\ A high speed device detected
          dup ['] make-root-hub-node catch  if	\ Process high speed device
-            drop ." Failed to probe root port " dup .d cr
+            drop ." Failed to make root hub node for port " dup .d cr
             true to probe-error?
          then
       then
@@ -105,6 +94,10 @@
       i portsc@ 2 and  if			\ Connection changed
 \         i rm-obsolete-children			\ Remove obsolete device nodes
          i probe-root-hub-port			\ Probe it
+      else
+         i port-is-hub?  if     ( phandle )     \ Already-connected hub?
+            reprobe-hub-node                    \ Check for changes on its ports
+         then
       then
    loop
 

Modified: dev/usb2/hcd/ehci/probehub.fth
==============================================================================
--- dev/usb2/hcd/ehci/probehub.fth	Wed Jan 26 20:01:33 2011	(r2151)
+++ dev/usb2/hcd/ehci/probehub.fth	Thu Jan 27 00:40:25 2011	(r2152)
@@ -31,39 +31,19 @@
 \ value and the /usb/hub/mouse hub20-port value are used in the qTD.
 
 : ?set-hub20-port  ( speed dev port -- )
-   " hub20-dev" my-parent ihandle>phandle get-package-property 0=  if
-      2drop nip swap speed-high <>  if
-         " hub20-port" int-property
-      else
-         drop
-      then
-   else
-      3drop
-   then
+   " hub20-dev" my-parent ihandle>phandle get-package-property 0=  if  ( speed dev port value$ )
+      2drop                                     ( speed dev port )
+      nip swap speed-high <>  if                ( port )
+         encode-int " hub20-port" property      ( )
+      else                                      ( speed )
+         drop                                   ( )
+      then                                      ( )
+   else                                         ( speed dev port )
+      3drop                                     ( )
+   then                                         ( )
 ;
 ' ?set-hub20-port to make-dev-property-hook
 
-: get-hub20-dev  ( -- hub-dev )
-   " hub20-dev" get-inherited-property 0=  if
-      decode-int nip nip
-   else
-      1
-   then
-;
-
-: get-hub20-port  ( port -- port' )
-   " hub20-port" get-inherited-property 0=  if
-      rot drop				( $ )
-      decode-int nip nip
-   then
-;
-
-\ Initialize USB 2.0 specific characteristics in di
-: set-usb20-char  ( port dev -- )
-        get-hub20-dev  over di-hub!
-   swap get-hub20-port swap di-port!
-;
-
 headers
 
 \ LICENSE_BEGIN

Modified: dev/usb2/hcd/hcd-call.fth
==============================================================================
--- dev/usb2/hcd/hcd-call.fth	Wed Jan 26 20:01:33 2011	(r2151)
+++ dev/usb2/hcd/hcd-call.fth	Thu Jan 27 00:40:25 2011	(r2152)
@@ -10,9 +10,28 @@
 : dma-alloc    ( size -- virt )              " dma-alloc" $call-parent    ;
 : dma-free     ( virt size -- )              " dma-free" $call-parent     ;
 
-: set-target  ( device -- )  " set-target" $call-parent  ;
-: probe-hub-xt  ( -- adr )   " probe-hub-xt" $call-parent  ;
-: set-pipe-maxpayload  ( size len -- ) " set-pipe-maxpayload" $call-parent  ;
+\ Probing support
+: set-target  ( device -- )
+   " set-target" $call-parent
+ ;
+: probe-hub-xt  ( -- adr )
+    " probe-hub-xt" $call-parent
+;
+: reprobe-hub-xt  ( -- adr )
+    " reprobe-hub-xt" $call-parent
+;
+: set-pipe-maxpayload  ( size len -- )
+   " set-pipe-maxpayload" $call-parent
+;
+: setup-new-node  ( port speed hub-port hub-dev -- false | port dev xt true )
+   " setup-new-node" $call-parent
+;
+: get-initial-descriptors  ( dev -- )
+   " get-initial-descriptors" $call-parent
+;
+: refresh-desc-bufs  ( dev -- )
+   " refresh-desc-bufs" $call-parent
+;
 
 \ Control pipe operations
 : control-get  ( adr len idx value rtype req -- actual usberr )

Modified: dev/usb2/hcd/ohci/probe.fth
==============================================================================
--- dev/usb2/hcd/ohci/probe.fth	Wed Jan 26 20:01:33 2011	(r2151)
+++ dev/usb2/hcd/ohci/probe.fth	Thu Jan 27 00:40:25 2011	(r2152)
@@ -4,7 +4,7 @@
 hex
 headers
 
-: enable-root-hub-port  ( port -- )
+: reset-port  ( port -- )
    >r
    h# 1.0002 r@ hc-rh-psta!		\ enable port
    10 r@ hc-rh-psta!			\ reset port
@@ -18,17 +18,17 @@
 ;
 
 : probe-root-hub-port  ( port -- )
-   dup hc-rh-psta@ 1 and 0=  if  drop exit  then	\ No device connected
-   ok-to-add-device? 0=  if  drop exit  then		\ Can't add another device
+   dup hc-rh-psta@ 1 and 0=  if  drop exit  then	( port )	\ No device connected
 
-   dup enable-root-hub-port		( port )
-   new-address				( port dev )
-   over hc-rh-psta@ 200 and  if  speed-low  else  speed-full  then over di-speed!
-
-   0 set-target				( port dev )	\ Address it as device 0
-   dup set-address  if  2drop exit  then ( port dev )	\ Assign it usb addr dev
-   dup set-target			( port dev )	\ Address it as device dev
-   make-device-node			( )
+   \ Reset the port to determine the speed
+   dup reset-port					( port )
+   dup hc-rh-psta@ 200 and  if  speed-low  else  speed-full  then	( port speed )
+
+   \ hub-port and hub-speed are irrelevant for OHCI (USB 1.1)
+   0 0							( port speed hub-port hub-dev )
+
+   \ Execute setup-new-node in root context and make-device-node in hub node context
+   setup-new-node  if  execute  then			( port dev xt )
 ;
 
 false value ports-powered?
@@ -99,6 +99,10 @@
 	    drop ." Failed to probe root port " i u. cr
          then
          3.0000 i hc-rh-psta!			\ Clear change bits
+      else
+         i port-is-hub?  if     ( phandle )     \ Already-connected hub?
+            reprobe-hub-node                    \ Check for changes on its ports
+         then
       then
    loop
    free-pkt-buf

Modified: dev/usb2/hcd/probehub.fth
==============================================================================
--- dev/usb2/hcd/probehub.fth	Wed Jan 26 20:01:33 2011	(r2151)
+++ dev/usb2/hcd/probehub.fth	Thu Jan 27 00:40:25 2011	(r2152)
@@ -7,63 +7,122 @@
 : set-usb20-char  ( port dev -- )  2drop  ;
 [then]
 
-: power-hub-port   ( port -- )      PORT_POWER  DR_PORT set-feature drop  ;
-: reset-hub-port   ( dev port -- )  PORT_RESET  DR_PORT set-feature drop  d# 20 ms  ;
+8 buffer: hub-buf                       \ For hub probing
+
+: power-hub-port   ( port -- )  PORT_POWER  DR_PORT " set-feature" $call-parent drop  ;
+: reset-hub-port   ( port -- )  PORT_RESET  DR_PORT " set-feature" $call-parent drop  d# 20 ms  ;
+: clear-status-change  ( port -- )  C_PORT_CONNECTION  DR_PORT " clear-feature" $call-parent drop  ;
+: parent-set-target  ( dev -- )  " set-target" $call-parent  ;
+: get-port-status  ( port -- error? )
+   hub-buf 4  2 pick   DR_PORT " get-status" $call-parent    ( port actual usberror )
+   nip  if                                   ( port )
+      ." Failed to get port status for port " u. cr
+      true                                   ( true )
+   else                                      ( port )
+      drop false                             ( false )
+   then                                      ( )
+;
+: port-status-changed?  ( hub-dev port -- false | connected? true )
+   swap parent-set-target       ( port )
+   dup get-port-status  if      ( port )
+      drop false exit           ( -- false )
+   then                         ( port )
+
+   hub-buf 2+ c@  1 and  if     ( port )
+      \ Status changed
+      clear-status-change       ( )
+      hub-buf c@ 1 and  0<>     ( connected? )
+      true                      ( connected? true )
+   else                         ( port )
+      drop false                ( false )
+   then
+;
 
 : probe-hub-port  ( hub-dev port -- )
-   swap set-target			( port )
-   dup reset-hub-port			( port )
+   \ Reset the port to determine the speed
+   swap parent-set-target			( port )
+   dup reset-hub-port				( port )
+
+   \ get-port-status fills hub-buf with connection status, speed, and other information
+   dup get-port-status  			( port error? )
+   over clear-status-change              	( port error? )
+   if  drop exit  then				( port )
 
-   gen-desc-buf 4 2 pick DR_PORT get-status nip  if
-      ." Failed to get port status for port " u. cr
-      exit
-   then					( port )
+   hub-buf c@ 1 and 0=  if  drop exit  then	\ No device connected
+   hub-buf le-w@ h# 600 and 9 >>  		( port speed )
 
-   gen-desc-buf c@ 1 and 0=  if	 drop exit  then	\ No device connected
-   ok-to-add-device?     0=  if  drop exit  then	\ Can't add another device
+   \ hub-port and hub-dev route USB 1.1 transactions through USB 2.0 hubs
+   over get-hub20-port  get-hub20-dev		( port speed hub-port hub-dev )
 
-   new-address				( port dev )
-   gen-desc-buf le-w@ h# 600 and 9 >> over di-speed!
-					( port dev )
-   2dup set-usb20-char			( port dev )
-
-   0 set-target				( port dev )	\ Address it as device 0
-   dup set-address  if  2drop exit  then ( port dev )	\ Assign it usb addr dev
-   dup set-target			( port dev )	\ Address it as device dev
-   make-device-node			( )
+   \ Execute setup-new-node in root context and make-device-node in hub node context
+   " setup-new-node" $call-parent  if  execute  then  ( )
 ;
 
-external
-: probe-hub  ( dev -- )
-   dup set-target			( hub-dev )
-   gen-desc-buf 8 0 0 HUB DR_HUB get-desc nip  if
+: hub-#ports  ( -- n )
+   hub-buf 8 0 0 HUB DR_HUB " get-desc" $call-parent nip  if
       ." Failed to get hub descriptor" cr
-      exit
+      0 exit
    then
+   hub-buf 2 + c@ 1+		( #ports )
+;
+: hub-delay  ( -- #2ms )  hub-buf 5 + c@  ;
 
-   gen-desc-buf dup 5 + c@ swap		( hub-dev #2ms adr )
-   2 + c@ 1+				( hub-dev #2ms #ports )
-
-   " configuration#" get-int-property set-config	( hub-dev #2ms #ports usberr )
-   if  2drop  ." Failed to set config for hub at " u. cr exit  then
-
-   tuck  1  ?do  i power-hub-port  loop  2* ms
-					( hub-dev #ports )
-   " usb-delay" ['] evaluate catch  if  ( hub-dev #ports x x )
-      2drop  d# 100                     ( hub-dev #ports ms )
-   then                                 ( hub-dev #ports ms )
+: power-hub-ports  ( #ports -- )
+   1  ?do  i power-hub-port  loop           ( )
+   
+   hub-delay 2* ms                          ( )
+
+   " usb-delay" ['] evaluate catch  if      ( )
+      2drop  d# 100                         ( ms )
+   then                                     ( ms )
    ms
+;
 
-   ( hub-dev #ports ) 1  ?do
-      dup i ['] probe-hub-port  catch  if
-         2drop
-         ." Failed to probe hub port " i u. cr
-      then
-   loop  drop
+: safe-probe-hub-port  ( hub-dev port -- )
+   tuck ['] probe-hub-port catch  if    ( port x x )
+      2drop  ." Failed to probe hub port " . cr  ( )
+   else                                 ( port )
+      drop                              ( )
+   then                                 ( )
+;
+external
+: probe-hub  ( dev -- )
+   dup parent-set-target		( hub-dev )
+   hub-#ports                           ( hub-dev #ports )
+
+   " configuration#" get-int-property
+   " set-config" $call-parent           ( hub-dev #ports usberr )
+   if  drop  ." Failed to set config for hub at " u. cr exit  then  ( hub-dev #ports )
+
+   dup power-hub-ports                  ( hub-dev #ports )
+
+   1  ?do                                       ( hub-dev )
+      dup i safe-probe-hub-port                 ( hub-dev )
+   loop                                         ( hub-dev )
+   drop                                         ( )
 ;
 
 : probe-hub-xt  ( -- adr )  ['] probe-hub  ;
 
+: do-reprobe-hub  ( dev -- )
+   dup parent-set-target			( hub-dev )
+   hub-#ports  1  ?do                           ( hub-dev )
+      dup i port-status-changed?  if            ( hub-dev connected? )
+         if                                     ( hub-dev )
+            dup i safe-probe-hub-port           ( hub-dev )
+     \   else  Handle disconnect
+         then                                   ( hub-dev )
+      else                                      ( hub-dev )
+         i port-is-hub?  if                     ( hub-dev phandle )
+            reprobe-hub-node                    ( hub-dev )
+         then                                   ( hub-dev )
+      then                                      ( hub-dev )
+   loop                                         ( hub-dev )
+   drop                                         ( )
+;
+
+: reprobe-hub-xt  ( -- adr )  ['] do-reprobe-hub  ;
+
 headers
 
 \ LICENSE_BEGIN

Modified: dev/usb2/hcd/uhci/loadpkg.fth
==============================================================================
--- dev/usb2/hcd/uhci/loadpkg.fth	Wed Jan 26 20:01:33 2011	(r2151)
+++ dev/usb2/hcd/uhci/loadpkg.fth	Thu Jan 27 00:40:25 2011	(r2152)
@@ -21,7 +21,7 @@
 fload ${BP}/dev/usb2/device/vendor.fth		\ Supported vendor/product tables
 fload ${BP}/dev/usb2/hcd/fcode.fth		\ Load fcode driver for child
 fload ${BP}/dev/usb2/hcd/device.fth		\ Make child node & its properties
-fload ${BP}/dev/usb2/hcd/uhci/probe.fth		\ Probe root hub
 fload ${BP}/dev/usb2/hcd/probehub.fth		\ Probe usb hub
+fload ${BP}/dev/usb2/hcd/uhci/probe.fth		\ Probe root hub
 
 

Modified: dev/usb2/hcd/uhci/probe.fth
==============================================================================
--- dev/usb2/hcd/uhci/probe.fth	Wed Jan 26 20:01:33 2011	(r2151)
+++ dev/usb2/hcd/uhci/probe.fth	Thu Jan 27 00:40:25 2011	(r2152)
@@ -4,31 +4,18 @@
 hex
 headers
 
-\ We mustn't wait more than 3 ms between releasing the reset and enabling
-\ the port to begin the SOF stream, otherwise some devices (e.g. pl2303)
-\ will go into suspend state and then not respond to set-address.
-: reset-root-hub-port  ( port -- )
-   dup >r  portsc@ h# 20e invert and    ( value r: port )  \ Clear reset, enable, status
-   dup h# 200 or  r@ portsc!	        ( value r: port )  \ Reset port
-   d# 30 ms                             ( value r: port )  \ > 10 ms - reset time
-   dup r@ portsc!                       ( value r: port )  \ Release reset
-   1 ms                                 ( value r: port )  \ > 5.3 uS - reconnect time
-   h# e or  r> portsc!	                ( )  \ Enable port and clear status
-;
-
 : probe-root-hub-port  ( port -- )
-   dup reset-root-hub-port
-   dup portsc@ 1 and 0=  if  drop exit  then		\ No device-connected
-   ok-to-add-device? 0=  if  drop exit  then		\ Can't add another device
-
-   new-address				( port dev )
-   over portsc@ 100 and  if  speed-low  else  speed-full  then
-   over di-speed!			( port dev )
-
-   0 set-target				( port dev )    \ Address it as device 0
-   dup set-address  if  2drop exit  then ( port dev )	\ Assign it usb addr dev
-   dup set-target			( port dev )    \ Address it as device dev
-   make-device-node			( )
+   \ Reset the port to perform connection status and speed detection
+   dup reset-port				( port )
+   dup portsc@ 1 and 0=  if  drop exit  then	( port )	\ No device-connected
+
+   dup portsc@ 100 and  if  speed-low  else  speed-full  then	( port speed )
+
+   \ hub-port and hub-speed are irrelevant for UHCI (USB 1.1)
+   0 0							( port speed hub-port hub-dev )
+
+   \ Execute setup-new-node in root context and make-device-node in hub node context
+   setup-new-node  if  execute  then			( )
 ;
 
 external
@@ -46,6 +33,10 @@
             drop ." Failed to probe root port " i .d cr
          then
          i portsc@ i portsc!			\ Clear change bits
+      else
+         i port-is-hub?  if     ( phandle )     \ Already-connected hub?
+            reprobe-hub-node                    \ Check for changes on its ports
+         then
       then
    loop
    free-pkt-buf

Modified: dev/usb2/hcd/uhci/uhci.fth
==============================================================================
--- dev/usb2/hcd/uhci/uhci.fth	Wed Jan 26 20:01:33 2011	(r2151)
+++ dev/usb2/hcd/uhci/uhci.fth	Thu Jan 27 00:40:25 2011	(r2152)
@@ -38,6 +38,18 @@
 : portsc@     ( port -- data )  2* 10 + uhci-w@  ;
 : portsc!     ( data port -- )  2* 10 + uhci-w!  ;
 
+\ We mustn't wait more than 3 ms between releasing the reset and enabling
+\ the port to begin the SOF stream, otherwise some devices (e.g. pl2303)
+\ will go into suspend state and then not respond to set-address.
+: reset-port  ( port -- )
+   dup >r  portsc@ h# 20e invert and    ( value r: port )  \ Clear reset, enable, status
+   dup h# 200 or  r@ portsc!	        ( value r: port )  \ Reset port
+   d# 30 ms                             ( value r: port )  \ > 10 ms - reset time
+   dup r@ portsc!                       ( value r: port )  \ Release reset
+   1 ms                                 ( value r: port )  \ > 5.3 uS - reconnect time
+   h# e or  r> portsc!	                ( )  \ Enable port and clear status
+;
+
 : reset-usb  ( -- )
    uhci-reg dup 0=  if  map-regs  then
    4 usbcmd!			\ Global reset

Modified: dev/usb2/pkt-data.fth
==============================================================================
--- dev/usb2/pkt-data.fth	Wed Jan 26 20:01:33 2011	(r2151)
+++ dev/usb2/pkt-data.fth	Thu Jan 27 00:40:25 2011	(r2152)
@@ -80,7 +80,7 @@
 
 \ Use tmp-l to make sure that le-l! and le-w! are atomic writes
 
-instance variable tmp-l
+variable tmp-l
 : le-w@   ( a -- w )   dup c@ swap ca1+ c@ bwjoin  ;
 : (le-w!) ( w a -- )   >r  wbsplit r@ ca1+ c! r> c!  ;
 : le-w!   ( w a -- )   swap tmp-l (le-w!) tmp-l w@ swap w!  ;

Modified: dev/usb2/pkt-func.fth
==============================================================================
--- dev/usb2/pkt-func.fth	Wed Jan 26 20:01:33 2011	(r2151)
+++ dev/usb2/pkt-func.fth	Thu Jan 27 00:40:25 2011	(r2152)
@@ -24,22 +24,6 @@
    repeat
 ;
 
-: get-class  ( dev-adr cfg-adr intfidx -- protocol subclass class )
-   rot dup 4 + c@ ?dup 0=  if		( cfg-adr intfidx dev-adr )
-      false to class-in-dev?		\ Class is not in device descriptor
-      drop find-intf-desc		( intf-adr )
-      dup 5 + c@ swap dup 6 + c@ swap 7 + c@
-   else					\ Class is in device-descriptor
-      true to class-in-dev?		( cfg-adr intfidx dev-adr class )
-      2swap 2drop			( dev-adr class )
-      swap dup 5 + c@ swap 6 + c@
-   then
-;
-
-: get-vid  ( adr -- vendor product rev )
-   dup 8 + le-w@ swap dup d# 10 + le-w@ swap c + le-w@
-;
-
 : unicode$>ascii$  ( adr -- actual )
    dup c@ 2 - 2/ swap 2 + over 0  ?do	( actual adr' )
       dup i 2* 1+ + c@ 0=  if		\ ASCII



More information about the openfirmware mailing list