| \ ***************************************************************************** |
| \ * Copyright (c) 2004, 2007 IBM Corporation |
| \ * All rights reserved. |
| \ * This program and the accompanying materials |
| \ * are made available under the terms of the BSD License |
| \ * which accompanies this distribution, and is available at |
| \ * http://www.opensource.org/licenses/bsd-license.php |
| \ * |
| \ * Contributors: |
| \ * IBM Corporation - initial implementation |
| \ ****************************************************************************/ |
| |
| |
| \ ---------------------------------------------------------------------------- |
| \ On detection of a hub after reading the device descriptor this package has to |
| \ be called so that the hub enumeration is done to idenitify the down stream |
| \ device |
| \ -------------------------------------------------------------------------- |
| \ OF properties |
| \ -------------------------------------------------------------------------- |
| |
| |
| s" hub" device-name |
| s" usb" device-type |
| 1 encode-int s" #address-cells" property |
| 0 encode-int s" #size-cells" property |
| |
| \ converts physical address to text unit string |
| |
| |
| : encode-unit ( port-addr -- unit-str unit-len ) 1 hex-encode-unit ; |
| |
| |
| \ Converts text unit string to phyical address |
| |
| |
| : decode-unit ( addr len -- port-addr ) 1 hex-decode-unit ; |
| |
| 0 VALUE new-device-address |
| 0 VALUE port-number |
| 0 VALUE MPS-DCP |
| 0 VALUE mps |
| 0 VALUE my-usb-address |
| |
| 00 value device-speed |
| |
| |
| \ Get parameters passed from the parent. |
| |
| : mps-property-set ( -- ) |
| s" HUB Compiling mps-property-set " usb-debug-print |
| s" USB-ADDRESS" get-my-property ( TRUE | prop-addr prop-len FALSE ) |
| IF |
| s" notpossible" usb-debug-print |
| ELSE |
| decode-int nip nip to my-usb-address |
| THEN |
| s" MPS-DCP" get-my-property ( TRUE | prop-addr prop-len FALSE ) |
| IF |
| s" MPS-DCP property not found Assuming 8 as MAX PACKET SIZE" ( str len ) |
| usb-debug-print |
| s" for the default control pipe" usb-debug-print |
| 8 to MPS-DCP |
| ELSE |
| s" MPS-DCP property found!!" usb-debug-print ( prop-addr prop-len FALSE ) |
| decode-int nip nip to MPS-DCP |
| THEN |
| ; |
| |
| |
| \ -------------------------------------------------------------------------- |
| \ Constant declarations |
| \ -------------------------------------------------------------------------- |
| |
| |
| 2303080000000000 CONSTANT hppwr-set |
| 2301080000000000 CONSTANT hppwr-clear |
| 2303040000000000 CONSTANT hprst-set |
| A300000000000400 CONSTANT hpsta-get |
| 2303010000000000 CONSTANT hpena-set |
| A006002900000000 CONSTANT hubds-get |
| 8 CONSTANT DEFAULT-CONTROL-MPS |
| 12 CONSTANT DEVICE-DESCRIPTOR-LEN |
| 9 CONSTANT CONFIG-DESCRIPTOR-LEN |
| 20 CONSTANT BULK-CONFIG-DESCRIPTOR-LEN |
| |
| |
| \ TODO: |
| \ CONFIG-DESCRIPTOR-LEN should be only 9. The interface |
| \ and endpoint descriptors returned along with config |
| \ descriptor are variable and 0x19 is a very wrong VALUE |
| \ to specify for this #define. |
| |
| |
| 1 CONSTANT DEVICE-DESCRIPTOR-TYPE |
| 1 CONSTANT DEVICE-DESCRIPTOR-TYPE-OFFSET |
| 4 CONSTANT DEVICE-DESCRIPTOR-DEVCLASS-OFFSET |
| 7 CONSTANT DEVICE-DESCRIPTOR-MPS-OFFSET |
| 9 CONSTANT HUB-DEVICE-CLASS |
| 0 CONSTANT NO-CLASS |
| |
| |
| \ -------------------------------------------------------------------------- |
| \ Temporary Variable declarations |
| \ -------------------------------------------------------------------------- |
| |
| 00 VALUE temp1 |
| 00 VALUE temp2 |
| 00 VALUE temp3 |
| 00 VALUE po2pg \ Power On to Power Good |
| |
| |
| \ -------------------------------------------------------------------------- |
| \ Buffer allocations |
| \ -------------------------------------------------------------------------- |
| |
| |
| VARIABLE setup-packet \ 8 bytes for setup packet |
| VARIABLE ch-buffer \ 1 byte character buffer |
| |
| INSTANCE VARIABLE dd-buffer |
| INSTANCE VARIABLE cd-buffer |
| |
| \ TODO: |
| \ Should arrive a proper value for the size of the "cd-buffer" |
| |
| 8 chars alloc-mem VALUE status-buffer |
| 9 chars alloc-mem VALUE hd-buffer |
| |
| |
| : (allocate-mem) ( -- ) |
| DEVICE-DESCRIPTOR-LEN chars alloc-mem dd-buffer ! |
| BULK-CONFIG-DESCRIPTOR-LEN chars alloc-mem cd-buffer ! |
| ; |
| |
| |
| : (de-allocate-mem) ( -- ) |
| dd-buffer @ ?dup IF |
| DEVICE-DESCRIPTOR-LEN free-mem |
| 0 dd-buffer ! |
| THEN |
| cd-buffer @ ?dup IF |
| BULK-CONFIG-DESCRIPTOR-LEN free-mem |
| 0 cd-buffer ! |
| THEN |
| ; |
| |
| |
| \ standard open firmware methods |
| |
| : open ( -- TRUE ) |
| (allocate-mem) |
| TRUE |
| ; |
| |
| : close ( -- ) |
| (de-allocate-mem) |
| ; |
| |
| |
| \ -------------------------------------------------------------------------- |
| \ Parent's method |
| \ -------------------------------------------------------------------------- |
| |
| |
| : controlxfer ( dir addr dlen setup-packet MPS ep-fun -- TRUE|FALSE ) |
| s" controlxfer" $call-parent |
| ; |
| |
| : control-std-set-address ( speedbit -- usb-address TRUE|FALSE ) |
| s" control-std-set-address" $call-parent |
| ; |
| |
| : control-std-get-device-descriptor |
| ( data-buffer data-len MPS funcAddr -- TRUE|FALSE ) |
| s" control-std-get-device-descriptor" $call-parent |
| ; |
| |
| : control-std-get-configuration-descriptor |
| ( data-buffer data-len MPS funcAddr -- TRUE|FALSE ) |
| s" control-std-get-configuration-descriptor" $call-parent |
| ; |
| |
| : control-std-get-maxlun |
| ( MPS fun-addr dir data-buff data-len -- TRUE|FALSE) |
| s" control-std-get-maxlun" $call-parent |
| ; |
| |
| : control-std-set-configuration |
| ( configvalue FuncAddr -- TRUE|FALSE ) |
| s" control-std-set-configuration" $call-parent |
| ; |
| |
| : control-std-get-string-descriptor |
| ( StringIndex data-buffer data-len MPS FuncAddr -- TRUE|FALSE ) |
| s" control-std-get-string-descriptor" $call-parent |
| ; |
| |
| : rw-endpoint |
| ( pt ed-type toggle buffer length mps address -- toggle TRUE|toggle FALSE ) |
| s" rw-endpoint" $call-parent |
| ; |
| |
| : debug-td ( -- ) |
| s" debug-td" $call-parent |
| ; |
| |
| |
| \ -------------------------------------------------------------------------- |
| \ HUB specific methods |
| \ -------------------------------------------------------------------------- |
| \ To bring on the power on a valid port of a hub with a valid USB address |
| \ -------------------------------------------------------------------------- |
| |
| |
| : control-hub-port-power-set ( port# -- TRUE|FALSE ) |
| hppwr-set setup-packet ! ( port#) |
| setup-packet 4 + c! |
| 0 0 0 setup-packet MPS-DCP my-usb-address controlxfer ( TRUE | FALSE ) |
| ; |
| |
| |
| \ -------------------------------------------------------------------------- |
| \ To put power off on ports where device detection or enumeration has failed |
| \ -------------------------------------------------------------------------- |
| |
| |
| : control-hub-port-power-clear ( port#-- TRUE|FALSE ) |
| hppwr-clear setup-packet ! ( port#) |
| setup-packet 4 + c! |
| 0 0 0 setup-packet MPS-DCP my-usb-address controlxfer ( TRUE|FALSE ) |
| ; |
| |
| |
| \ ------------------------------------------------------------------------- |
| \ To reset a valid port of a hub with a valid USB |
| \ address |
| \ -------------------------------------------------------------------------- |
| |
| |
| : control-hub-port-reset-set ( port# -- TRUE|FALSE ) |
| hprst-set setup-packet ! ( port# ) |
| setup-packet 4 + c! |
| 0 0 0 setup-packet MPS-DCP my-usb-address controlxfer ( TRUE|FALSE ) |
| ; |
| |
| |
| \ ------------------------------------------------------------------------- |
| \ To enable a particular valid port of a hub with a valid USB address |
| \ ------------------------------------------------------------------------- |
| |
| |
| : control-hub-port-enable ( port# -- TRUE|FALSE ) |
| hpena-set setup-packet ! ( port# ) |
| setup-packet 4 + c! |
| 0 0 0 setup-packet MPS-DCP my-usb-address controlxfer ( TRUE|FALSE ) |
| ; |
| |
| |
| \ ------------------------------------------------------------------------- |
| \ To get the status of a valid port of a hub with |
| \ a valid USB address |
| \ ------------------------------------------------------------------------- |
| |
| |
| : control-hub-port-status-get ( buffer port# -- TRUE|FALSE ) |
| hpsta-get setup-packet ! ( buffer port# ) |
| setup-packet 4 + c! ( buffer ) |
| 0 swap 4 setup-packet MPS-DCP my-usb-address controlxfer ( TRUE|FALSE ) |
| ; |
| |
| |
| \ -------------------------------------------------------------------------- |
| \ To get the hub descriptor to understand how many ports are vailable and the |
| \ specs of those ports |
| \ --------------------------------------------------------------------------- |
| |
| |
| : control-get-hub-descriptor ( buffer buffer-length -- TRUE|FALSE ) |
| hubds-get setup-packet ! |
| dup setup-packet 6 + w!-le ( buffer buffer-length ) |
| 0 -rot setup-packet MPS-DCP my-usb-address controlxfer ( TRUE|FALSE ) |
| ; |
| |
| |
| s" usb-enumerate.fs" INCLUDED |
| |
| |
| : hub-configure-port ( port# -- ) |
| |
| \ Step 1: set the Port Power |
| usb-test-flag |
| IF |
| ." Port: " dup . cr |
| 150 ms \ wait for bad devices |
| THEN |
| |
| dup control-hub-port-power-set drop ( port# ) |
| BEGIN ( port# ) |
| status-buffer 4 erase ( port# ) |
| status-buffer over control-hub-port-status-get drop ( port# ) |
| status-buffer w@-le 102 and 0= ( port# TRUE|FALSE ) |
| WHILE ( port# ) |
| REPEAT ( port# ) |
| po2pg 3 * ms \ wait for bPwrOn2PwrGood*3 ms |
| |
| usb-test-flag |
| IF |
| 150 ms |
| THEN |
| \ STEP 2: Reset the port. |
| |
| dup control-hub-port-reset-set drop ( port# ) |
| BEGIN ( port# ) |
| status-buffer 4 erase ( port# ) |
| status-buffer over control-hub-port-status-get drop ( port# ) |
| status-buffer w@-le 10 and ( port# TRUE|FALSE ) |
| usb-test-flag |
| IF |
| s" Port Satus: " status-buffer w@-le usb-debug-print-val |
| THEN |
| WHILE ( port# ) |
| REPEAT ( port# ) |
| |
| \ after reset set port enable -important- |
| dup control-hub-port-enable drop ( port# ) |
| |
| usb-test-flag |
| IF |
| 10 ms |
| THEN |
| |
| \ STEP 3: Check if a device is connected to the |
| \ port. |
| |
| status-buffer 4 erase ( port# ) |
| status-buffer over control-hub-port-status-get drop ( port# ) |
| status-buffer w@-le 103 and 103 <> ( port# TRUE|FALSE ) |
| s" Port status bits: " status-buffer w@-le usb-debug-print-val |
| IF ( port# ) |
| drop |
| s" Connect status: No device connected " usb-debug-print |
| EXIT |
| THEN |
| |
| \ New addition: Sometimes the port status returns connected |
| \ but Set address was failing. Analysis showed that such |
| \ ports do not set this bit to 1. |
| |
| status-buffer 2 + w@-le 1 and 1 <> ( port# ) |
| IF ( port# ) |
| drop |
| s" No device connected to port- set addresss failed" usb-debug-print |
| EXIT |
| THEN |
| s" HUB: New device found!!!" usb-debug-print |
| \ s" HUB: Status buffer first word -> " usb-debug-print |
| \ s" HUB: Status buffer second word -> " usb-debug-print |
| |
| \ STEP 4: Assign an address to this device. |
| |
| status-buffer w@-le 200 and 4 lshift \ get speed bit |
| dup to device-speed \ store speed bit |
| ( port# speedbit ) |
| control-std-set-address ( port# usb-addr TRUE|FALSE ) |
| 50 ms ( port# usb-addr TRUE|FALSE ) |
| debug-td ( port# usb-addr TRUE|FALSE ) |
| IF ( port# usb-addr ) |
| device-speed or ( port# usb-addr+speedbit ) |
| to new-device-address ( port# ) |
| to port-number |
| dd-buffer @ DEVICE-DESCRIPTOR-LEN erase |
| dd-buffer @ DEFAULT-CONTROL-MPS DEFAULT-CONTROL-MPS new-device-address |
| ( buffer mps mps usb-addr ) |
| control-std-get-device-descriptor ( TRUE|FALSE ) |
| IF |
| dd-buffer @ DEVICE-DESCRIPTOR-TYPE-OFFSET + c@ ( descriptor-type ) |
| DEVICE-DESCRIPTOR-TYPE <> ( TRUE|FALSE ) |
| IF |
| s" HUB: ERROR!! Invalid Device Descriptor for the new device" |
| usb-debug-print |
| ELSE |
| dd-buffer @ DEVICE-DESCRIPTOR-MPS-OFFSET + c@ to mps |
| |
| \ Re-read the device descriptor again with the known MPS. |
| |
| dd-buffer @ DEVICE-DESCRIPTOR-LEN erase |
| dd-buffer @ DEVICE-DESCRIPTOR-LEN mps new-device-address |
| ( buffer descp-len mps usb-addr ) |
| \ s" DEVICE DESCRIPTOR: " usb-debug-print |
| control-std-get-device-descriptor drop |
| \ dd-buffer usb-debug-print-val |
| create-usb-device-tree |
| THEN |
| ELSE |
| s" ERROR!! Failed to get device descriptor" usb-debug-print |
| THEN |
| ELSE ( port# ) |
| s" USB Set Adddress failed!!" usb-debug-print ( port# ) |
| s" Clearing Port Power..." usb-debug-print ( port# ) |
| control-hub-port-power-clear ( TRUE|FALSE ) |
| IF |
| s" Port power down " usb-debug-print |
| ELSE |
| s" Unable to clear port power!!!" usb-debug-print |
| THEN |
| THEN |
| ; |
| |
| |
| \ --------------------------------------------------------------------------- |
| \ To enumerate all the valid ports of hub |
| \ TODO: |
| \ 1. Remove hardcoded constants. |
| \ 2. Remove Endian Dependencies. |
| \ 3. Return values of controlxfer should be checked. |
| \ --------------------------------------------------------------------------- |
| |
| : hub-enumerate ( -- ) |
| cd-buffer @ CONFIG-DESCRIPTOR-LEN erase |
| |
| \ Get HUB configuration and SET the configuration |
| \ note: remove hard-coded constants. |
| |
| cd-buffer @ CONFIG-DESCRIPTOR-LEN MPS-DCP my-usb-address |
| ( buffer descp-len mps usb-address ) |
| control-std-get-configuration-descriptor drop |
| cd-buffer @ 1+ c@ 2 <> IF |
| s" Unable to read configuration descriptor" usb-debug-print |
| EXIT |
| THEN |
| cd-buffer @ 4 + c@ 1 <> IF |
| s" Not a valid HUB config descriptor" usb-debug-print |
| EXIT |
| THEN |
| |
| \ TODO: Do further checkings on the returned Configuration descriptor |
| \ before proceeding to accept it. |
| |
| cd-buffer @ 5 + c@ to temp1 \ Store the configuration in temp1 |
| temp1 my-usb-address control-std-set-configuration drop |
| my-usb-address to temp1 |
| hd-buffer 9 erase |
| hd-buffer 9 control-get-hub-descriptor drop |
| |
| \ PENDING: 1. Check Return value. |
| \ 2. HUB descriptor size is variable. Currently we r hardcoding |
| \ a value of 9. |
| |
| hd-buffer 2 + c@ to temp2 |
| s" HUB: Found " usb-debug-print \ temp2 . |
| s" number of downstream hub ports! : " temp2 usb-debug-print-val |
| hd-buffer 5 + c@ to po2pg \ get bPwrOn2PwrGood |
| temp2 1+ 1 DO |
| I hub-configure-port |
| LOOP |
| ; |
| |
| |
| \ -------------------------------------------------------------------------- |
| \ To initialize hub |
| \ -------------------------------------------------------------------------- |
| |
| (allocate-mem) |
| mps-property-set |
| hub-enumerate |
| (de-allocate-mem) |
| |