Annotation of qemu/roms/SLOF/slof/fs/usb/usb-hub.fs, revision 1.1.1.2

1.1       root        1: \ *****************************************************************************
                      2: \ * Copyright (c) 2004, 2008 IBM Corporation
                      3: \ * All rights reserved.
                      4: \ * This program and the accompanying materials
                      5: \ * are made available under the terms of the BSD License
                      6: \ * which accompanies this distribution, and is available at
                      7: \ * http://www.opensource.org/licenses/bsd-license.php
                      8: \ *
                      9: \ * Contributors:
                     10: \ *     IBM Corporation - initial implementation
                     11: \ ****************************************************************************/
                     12: 
                     13: 
                     14: \ ----------------------------------------------------------------------------
                     15: \ On detection of a hub after reading the device descriptor this package has to
                     16: \ be called so that the hub enumeration is done to idenitify the down stream 
                     17: \ device  
                     18: \ --------------------------------------------------------------------------
                     19: \ OF properties
                     20: \ --------------------------------------------------------------------------
                     21: 
                     22: 
                     23: s" hub" device-name
                     24: s" usb" device-type
                     25: 1 encode-int s" #address-cells" property
                     26: 0 encode-int s" #size-cells" property
                     27: 
                     28: \ converts physical address to text unit string 
                     29: 
                     30: 
                     31: : encode-unit ( port-addr -- unit-str unit-len )  1 hex-encode-unit ;
                     32: 
                     33: 
                     34: \ Converts text unit string to phyical address 
                     35: 
                     36: 
                     37: : decode-unit ( addr len -- port-addr ) 1 hex-decode-unit ;
                     38: 
                     39: 0 VALUE new-device-address
                     40: 0 VALUE port-number
                     41: 0 VALUE MPS-DCP
                     42: 0 VALUE mps
                     43: 0 VALUE my-usb-address
                     44: 
                     45: 00 value device-speed
                     46: 
                     47: 
                     48: \ Get parameters passed from the parent.
                     49: 
                     50: : mps-property-set ( -- )
                     51:    s"  HUB Compiling mps-property-set " usb-debug-print
                     52:    s" USB-ADDRESS" get-my-property ( TRUE | prop-addr prop-len FALSE )
                     53:    IF
                     54:       s" notpossible" usb-debug-print
                     55:    ELSE
                     56:       decode-int nip nip to my-usb-address
                     57:    THEN  
                     58:    s" MPS-DCP" get-my-property ( TRUE | prop-addr prop-len FALSE )
                     59:    IF 
                     60:       s" MPS-DCP property not found Assuming 8 as MAX PACKET SIZE" ( str len )  
                     61:       usb-debug-print
                     62:       s" for the default control pipe"  usb-debug-print
                     63:       8 to MPS-DCP
                     64:    ELSE
                     65:       s" MPS-DCP property found!!" usb-debug-print ( prop-addr prop-len FALSE )
                     66:       decode-int nip nip to MPS-DCP
                     67:    THEN
                     68: ;
                     69: 
                     70: 
                     71: \ --------------------------------------------------------------------------
                     72: \ Constant declarations
                     73: \ --------------------------------------------------------------------------
                     74: 
                     75: 
                     76: 2303080000000000 CONSTANT hppwr-set
                     77: 2301080000000000 CONSTANT hppwr-clear
                     78: 2303040000000000 CONSTANT hprst-set
                     79: A300000000000400 CONSTANT hpsta-get
                     80: 2303010000000000 CONSTANT hpena-set
                     81: A006002900000000 CONSTANT hubds-get
                     82: 8  CONSTANT DEFAULT-CONTROL-MPS
                     83: 12 CONSTANT DEVICE-DESCRIPTOR-LEN
                     84: 9  CONSTANT CONFIG-DESCRIPTOR-LEN
                     85: 20 CONSTANT BULK-CONFIG-DESCRIPTOR-LEN
                     86: 
                     87: 
                     88: \ TODO:
                     89: \ CONFIG-DESCRIPTOR-LEN should be only 9. The interface
                     90: \ and endpoint descriptors returned along with config
                     91: \ descriptor are variable and 0x19 is a very wrong VALUE
                     92: \ to specify for this #define.
                     93: 
                     94: 
                     95: 1 CONSTANT DEVICE-DESCRIPTOR-TYPE
                     96: 1 CONSTANT DEVICE-DESCRIPTOR-TYPE-OFFSET
                     97: 4 CONSTANT DEVICE-DESCRIPTOR-DEVCLASS-OFFSET
                     98: 7 CONSTANT DEVICE-DESCRIPTOR-MPS-OFFSET
                     99: 9 CONSTANT HUB-DEVICE-CLASS
                    100: 0 CONSTANT NO-CLASS
                    101: 
                    102: 
                    103: \ --------------------------------------------------------------------------
                    104: \ Temporary Variable declarations
                    105: \ --------------------------------------------------------------------------
                    106: 
                    107: 00 VALUE temp1
                    108: 00 VALUE temp2
                    109: 00 VALUE temp3
                    110: 00 VALUE po2pg            \ Power On to Power Good
                    111: 
                    112: 
                    113: \ --------------------------------------------------------------------------
1.1.1.2 ! root      114: \ DMA buffer allocations
1.1       root      115: \ --------------------------------------------------------------------------
                    116: 
1.1.1.2 ! root      117: : dma-alloc    s" dma-alloc" $call-parent ;
        !           118: : dma-map-in   s" dma-map-in" $call-parent ;
        !           119: : dma-map-out  s" dma-map-out" $call-parent ;
        !           120: : dma-free     s" dma-free" $call-parent ;
1.1       root      121: 
1.1.1.2 ! root      122: 
        !           123: 0 INSTANCE VALUE setup-packet     \ 8 bytes for setup packet
        !           124: 0 INSTANCE VALUE ch-buffer        \ 1 byte character buffer
1.1       root      125: 
                    126: INSTANCE VARIABLE dd-buffer
                    127: INSTANCE VARIABLE cd-buffer
                    128: 
                    129: \ TODO:
                    130: \ Should arrive a proper value for the size of the "cd-buffer"
                    131: 
1.1.1.2 ! root      132: STRUCT
        !           133:    8 FIELD >setup-packet                         \ 8 bytes for setup packet
        !           134:    DEVICE-DESCRIPTOR-LEN FIELD >dd-buffer
        !           135:    BULK-CONFIG-DESCRIPTOR-LEN FIELD >cd-buffer
        !           136:    8 chars FIELD >status-buffer
        !           137:    9 chars FIELD >hd-buffer
        !           138:    1 chars FIELD >ch-buffer                      \ character buffer
        !           139: CONSTANT /hub-buf
1.1       root      140: 
1.1.1.2 ! root      141: 0 INSTANCE VALUE hub-buf
        !           142: 0 INSTANCE VALUE hub-buf-phys
1.1       root      143: 
                    144: : (allocate-mem)  ( -- )
1.1.1.2 ! root      145:    /hub-buf dma-alloc TO hub-buf
        !           146:    hub-buf /hub-buf 0 dma-map-in TO hub-buf-phys
        !           147: 
        !           148:    hub-buf >setup-packet TO setup-packet
        !           149:    hub-buf >ch-buffer TO ch-buffer
        !           150:    hub-buf >dd-buffer dd-buffer !
        !           151:    hub-buf >cd-buffer cd-buffer !
        !           152: 
        !           153:    s" hub-buf = " hub-buf usb-debug-print-val
1.1       root      154: ;
                    155: 
                    156: 
                    157: : (de-allocate-mem)  ( -- )
1.1.1.2 ! root      158:    hub-buf hub-buf-phys /hub-buf dma-map-out
        !           159:    hub-buf /hub-buf dma-free
        !           160:    0 TO hub-buf
        !           161:    0 TO hub-buf-phys
        !           162:    0 TO setup-packet
        !           163:    0 TO ch-buffer
        !           164:    0 dd-buffer !
        !           165:    0 cd-buffer !
1.1       root      166: ;
                    167: 
                    168: 
                    169: \ standard open firmware methods 
                    170: 
                    171: : open ( -- TRUE )
                    172:    (allocate-mem)
                    173:    TRUE
                    174: ;
                    175: 
                    176: : close ( -- )
                    177:    (de-allocate-mem)
                    178: ;
                    179: 
                    180: 
                    181: \ --------------------------------------------------------------------------
                    182: \ Parent's method
                    183: \ --------------------------------------------------------------------------
                    184: 
                    185: 
                    186: : controlxfer ( dir addr dlen setup-packet MPS ep-fun -- TRUE|FALSE )
                    187:    s" controlxfer" $call-parent 
                    188: ;
                    189: 
                    190: : control-std-set-address ( speedbit -- usb-address TRUE|FALSE )
                    191:    s" control-std-set-address" $call-parent 
                    192: ; 
                    193: 
                    194: : control-std-get-device-descriptor 
                    195:    ( data-buffer data-len MPS funcAddr -- TRUE|FALSE )
                    196:    s" control-std-get-device-descriptor" $call-parent 
                    197: ;
                    198: 
                    199: : control-std-get-configuration-descriptor 
                    200:    ( data-buffer data-len MPS funcAddr -- TRUE|FALSE )
                    201:    s" control-std-get-configuration-descriptor" $call-parent 
                    202: ;
                    203: 
                    204: : control-std-get-maxlun
                    205:    ( MPS fun-addr dir data-buff data-len -- TRUE|FALSE )
                    206:    s" control-std-get-maxlun" $call-parent 
                    207: ;
                    208: 
                    209: : control-std-set-configuration 
                    210:    ( configvalue FuncAddr -- TRUE|FALSE )
                    211:    s" control-std-set-configuration" $call-parent 
                    212: ;
                    213: 
                    214: : control-std-get-string-descriptor
                    215:    ( StringIndex data-buffer data-len MPS FuncAddr -- TRUE|FALSE )
                    216:    s" control-std-get-string-descriptor" $call-parent 
                    217: ;
                    218: 
                    219: : rw-endpoint 
                    220:    ( pt ed-type toggle buffer length mps address -- toggle TRUE|toggle FALSE )
                    221:    s" rw-endpoint" $call-parent 
                    222: ;
                    223: 
                    224: : debug-td ( -- )
                    225:    s" debug-td" $call-parent
                    226: ;
                    227: 
                    228: \ *** NEW ****
                    229: : control-bulk-reset ( MPS fun-addr dir data-buff data-len -- TRUE | FALSE )
                    230:    s" control-bulk-reset" $call-parent
                    231: ;
                    232: 
                    233: 
                    234: \ --------------------------------------------------------------------------
                    235: \ HUB specific methods
                    236: \ --------------------------------------------------------------------------
                    237: \ To bring on the power on a valid port of a hub with a valid USB address
                    238: \ --------------------------------------------------------------------------
                    239: 
                    240: 
                    241: : control-hub-port-power-set  ( port# -- TRUE|FALSE )
                    242:    hppwr-set setup-packet !    ( port#)
                    243:    setup-packet 4 + c!
                    244:    0 0 0 setup-packet MPS-DCP my-usb-address controlxfer ( TRUE | FALSE )
                    245: ;
                    246: 
                    247: 
                    248: \ --------------------------------------------------------------------------
                    249: \ To put power off on ports where device detection or enumeration has failed
                    250: \ --------------------------------------------------------------------------
                    251: 
                    252: 
                    253: : control-hub-port-power-clear ( port#-- TRUE|FALSE )
                    254:    hppwr-clear setup-packet !  ( port#)
                    255:    setup-packet 4 + c!
                    256:    0 0 0 setup-packet MPS-DCP my-usb-address controlxfer ( TRUE|FALSE )
                    257: ;
                    258: 
                    259: 
                    260: \ -------------------------------------------------------------------------
                    261: \ To reset a valid port of a hub with a valid USB 
                    262: \ address
                    263: \ --------------------------------------------------------------------------
                    264: 
                    265: 
                    266: : control-hub-port-reset-set ( port# -- TRUE|FALSE )
                    267:    hprst-set setup-packet !    ( port# )
                    268:    setup-packet 4 + c!
                    269:    0 0 0 setup-packet MPS-DCP my-usb-address controlxfer ( TRUE|FALSE )
                    270: ;
                    271: 
                    272: 
                    273: \ -------------------------------------------------------------------------
                    274: \ To enable a particular valid port of a hub with a valid USB address
                    275: \ -------------------------------------------------------------------------
                    276: 
                    277: 
                    278: : control-hub-port-enable ( port# -- TRUE|FALSE )
                    279:    hpena-set setup-packet !    ( port# )
                    280:    setup-packet 4 +  c!
                    281:    0 0 0 setup-packet MPS-DCP my-usb-address controlxfer ( TRUE|FALSE )
                    282: ;
                    283: 
                    284: 
                    285: \ -------------------------------------------------------------------------
                    286: \ To get the status of a valid port of a hub with 
                    287: \ a valid USB address
                    288: \ -------------------------------------------------------------------------
                    289: 
                    290: 
                    291: : control-hub-port-status-get ( buffer port# -- TRUE|FALSE )
                    292:    hpsta-get setup-packet !    ( buffer port# )
                    293:    setup-packet 4 + c!         ( buffer )
                    294:    0 swap 4 setup-packet MPS-DCP my-usb-address controlxfer ( TRUE|FALSE )
                    295: ;
                    296: 
                    297: 
                    298: \ --------------------------------------------------------------------------
                    299: \ To get the hub descriptor to understand how many ports are vailable and the 
                    300: \ specs of those ports
                    301: \ ---------------------------------------------------------------------------
                    302: 
                    303: 
                    304: : control-get-hub-descriptor ( buffer buffer-length -- TRUE|FALSE )
                    305:    hubds-get setup-packet ! 
                    306:    dup setup-packet 6 + w!-le ( buffer buffer-length )
                    307:    0 -rot setup-packet MPS-DCP my-usb-address controlxfer ( TRUE|FALSE )
                    308: ;
                    309: 
                    310: 
                    311: s" usb-enumerate.fs" INCLUDED
                    312: 
                    313: 
                    314: : hub-configure-port ( port# -- )
                    315: 
                    316: \ this port has been powered on
                    317: \ send reset to enable port and
                    318: \ start device detection by hub
                    319: \ some devices require a long timeout here (10s)
                    320: 
                    321:    \ Step 1: check if reset state ended
                    322: 
                    323:    BEGIN                               ( port# )
1.1.1.2 ! root      324:       hub-buf >status-buffer 4 erase    ( port# )
        !           325:       hub-buf >status-buffer over
        !           326:       control-hub-port-status-get drop  ( port# ) 
        !           327:       hub-buf >status-buffer w@-le 102 and 0=   ( port# TRUE|FALSE )
1.1       root      328:    WHILE                               ( port# )
1.1.1.2 ! root      329:    REPEAT                               ( port# )
1.1       root      330:    po2pg 3 * ms    \ wait for bPwrOn2PwrGood*3 ms
                    331:    
                    332:    \ STEP 2: Reset the port.
                    333:    \         (this also enables the port)
                    334:    dup control-hub-port-reset-set drop ( port# )
                    335:    BEGIN                               ( port# )
1.1.1.2 ! root      336:       hub-buf >status-buffer 4 erase    ( port# )
        !           337:       hub-buf >status-buffer over
        !           338:       control-hub-port-status-get drop  ( port# ) 
        !           339:       hub-buf >status-buffer w@-le 10 and  ( port# TRUE|FALSE )
1.1       root      340:    WHILE                               ( port# )
                    341:    REPEAT                              ( port# )
                    342: 
                    343:    \ STEP 3: Check if a device is connected to the port.
                    344: 
1.1.1.2 ! root      345:    hub-buf >status-buffer 4 erase       ( port# )
        !           346:    hub-buf >status-buffer over
        !           347:    control-hub-port-status-get drop     ( port# ) 
        !           348:    hub-buf >status-buffer w@-le  103 and  103 <>   ( port# TRUE|FALSE )
        !           349:    s" Port status bits: " hub-buf >status-buffer w@-le usb-debug-print-val
1.1       root      350:    IF                                  ( port# ) 
1.1.1.2 ! root      351:       drop
1.1       root      352:       s" Connect status: No device connected "  usb-debug-print
                    353:       EXIT 
                    354:    THEN 
                    355: 
                    356: 
                    357:    \ STEP 4: Assign an address to this device.
                    358: 
1.1.1.2 ! root      359:    hub-buf >status-buffer w@-le 200 and 4 lshift  \ get speed bit
        !           360:    dup to device-speed                            \ store speed bit
1.1       root      361:                                 ( port# speedbit )
                    362:    control-std-set-address     ( port# usb-addr TRUE|FALSE )
                    363:    50 ms                       ( port# usb-addr TRUE|FALSE )
                    364:    debug-td                    ( port# usb-addr TRUE|FALSE )
                    365:    IF                          ( port# usb-addr )
                    366:       device-speed or           ( port# usb-addr+speedbit )
                    367:       to new-device-address     ( port# )
                    368:       to port-number
                    369:       dd-buffer @ DEVICE-DESCRIPTOR-LEN erase
                    370:       dd-buffer @ DEFAULT-CONTROL-MPS DEFAULT-CONTROL-MPS new-device-address
                    371:       ( buffer mps mps usb-addr ) 
                    372:       control-std-get-device-descriptor     ( TRUE|FALSE )
                    373:       IF
                    374:          dd-buffer @ DEVICE-DESCRIPTOR-TYPE-OFFSET + c@ ( descriptor-type )
                    375:          DEVICE-DESCRIPTOR-TYPE <>          ( TRUE|FALSE )
                    376:          IF 
                    377:             s" HUB: ERROR!! Invalid Device Descriptor for the new device"
                    378:             usb-debug-print
                    379:          ELSE
                    380:             dd-buffer @ DEVICE-DESCRIPTOR-MPS-OFFSET + c@ to mps
                    381: 
                    382:             \ Re-read the device descriptor again with the known MPS.
                    383: 
                    384:             dd-buffer @ DEVICE-DESCRIPTOR-LEN erase
                    385:             dd-buffer @ DEVICE-DESCRIPTOR-LEN mps new-device-address
                    386:             ( buffer descp-len mps usb-addr )
                    387:             \ s" DEVICE DESCRIPTOR: " usb-debug-print
                    388:             control-std-get-device-descriptor invert
                    389:             IF
                    390:                s" ** reading dev-descriptor failed ** " usb-debug-print
                    391:             THEN
                    392:             create-usb-device-tree
                    393:          THEN
                    394:       ELSE
                    395:          s" ERROR!! Failed to get device descriptor" usb-debug-print 
                    396:       THEN
                    397:    ELSE                                                    ( port# )
                    398:       s" USB Set Adddress failed!!" usb-debug-print ( port# )
                    399:       s" Clearing Port Power..."  usb-debug-print   ( port# )
                    400:       control-hub-port-power-clear                 ( TRUE|FALSE )
                    401:       IF 
                    402:          s" Port power down " usb-debug-print
                    403:       ELSE
                    404:          s" Unable to clear port power!!!" usb-debug-print
                    405:       THEN
                    406:    THEN
                    407: ;
                    408: 
                    409: 
                    410: \ ---------------------------------------------------------------------------
                    411: \ To enumerate all the valid ports of hub
                    412: \ TODO:
                    413: \ 1. Remove hardcoded constants.
                    414: \ 2. Remove Endian Dependencies.
                    415: \ 3. Return values of controlxfer should be checked. 
                    416: \ ---------------------------------------------------------------------------
                    417: 
                    418: : hub-enumerate ( -- )
                    419:    cd-buffer @ CONFIG-DESCRIPTOR-LEN erase
                    420: 
                    421:    \ Get HUB configuration and SET the configuration
                    422:    \ note: remove hard-coded constants.
                    423: 
                    424:    cd-buffer @ CONFIG-DESCRIPTOR-LEN MPS-DCP my-usb-address 
                    425:    ( buffer descp-len mps usb-address )
                    426:    control-std-get-configuration-descriptor drop 
                    427:    cd-buffer @ 1+ c@ 2 <>  IF
                    428:       s" Unable to read configuration descriptor" usb-debug-print
                    429:       EXIT 
                    430:    THEN 
                    431:    cd-buffer @ 4 + c@ 1 <> IF
                    432:       s" Not a valid HUB config descriptor" usb-debug-print 
                    433:       EXIT 
                    434:    THEN 
                    435: 
                    436:    \ TODO: Do further checkings on the returned Configuration descriptor
                    437:    \ before proceeding to accept it.
                    438: 
                    439:    cd-buffer @ 5 + c@ to temp1 \ Store the configuration in temp1
                    440:    temp1 my-usb-address control-std-set-configuration drop
                    441:    my-usb-address to temp1
1.1.1.2 ! root      442:    hub-buf >hd-buffer 9 erase
        !           443:    hub-buf >hd-buffer 9 control-get-hub-descriptor drop
1.1       root      444: 
                    445:    \ PENDING: 1. Check Return value.
                    446:    \          2. HUB descriptor size is variable. Currently we r hardcoding
                    447:    \             a value of 9.
                    448: 
1.1.1.2 ! root      449:    hub-buf >hd-buffer 2 + c@ to temp2     \ number of downstream ports
1.1       root      450: 
                    451:    s" HUB: Found " usb-debug-print
                    452:    s" number of downstream hub ports! : " temp2 usb-debug-print-val
1.1.1.2 ! root      453:    hub-buf >hd-buffer 5 + c@ to po2pg     \ get bPwrOn2PwrGood
1.1       root      454: 
                    455:    \ power on all present hub ports
                    456:    \ to allow slow devices to set up
                    457: 
                    458:    temp2 1+ 1 DO
                    459:       i control-hub-port-power-set drop
                    460:       d# 20 ms
                    461:    LOOP
                    462: 
                    463:    d# 200 ms      \ some devices need a long time (10s)
                    464: 
                    465:    \ now start detection and configuration for these ports
                    466:    
                    467:    temp2 1+ 1 DO
                    468:        s" hub-configure-port: " i usb-debug-print-val
                    469:        i hub-configure-port
                    470:    LOOP
                    471: ; 
                    472: 
                    473: 
                    474: \ --------------------------------------------------------------------------  
                    475: \ To initialize hub
                    476: \ --------------------------------------------------------------------------
                    477: 
                    478: (allocate-mem)
                    479: mps-property-set
                    480: hub-enumerate
                    481: (de-allocate-mem)
                    482: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.