Annotation of qemu/roms/SLOF/slof/fs/usb/usb-support.fs, revision 1.1

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: 0 value NEXT-TD
        !            14: 
        !            15: 0 VALUE num-tds
        !            16: 0 VALUE td-retire-count
        !            17: 0 VALUE saved-tail
        !            18: 0 VALUE poll-timer
        !            19: VARIABLE controlxfer-cmd
        !            20: 
        !            21: \  Allocate an ED and populate it
        !            22: 
        !            23: : (ed-prepare) ( dir addr dlen setup-packet MPS ep-fun --
        !            24:                  FALSE | dir addr dlen ed-ptr setup-ptr )
        !            25:    allocate-ed dup 0=  IF ( dir addr dlen setup-packet MPS ep-fun ed-ptr )
        !            26:       drop 3drop 2drop FALSE EXIT  ( FALSE )
        !            27:    THEN
        !            28:    TO temp1               ( dir addr dlen setup-packet MPS ep-fun )
        !            29:    temp1 zero-out-an-ed-except-link ( dir addr dlen setup-packet MPS ep-fun )
        !            30:    temp1 ed>eattr l@-le or temp1 ed>eattr l!-le ( dir addr dlen setup-ptr MPS )
        !            31:    dup TO temp2 10 lshift temp1 ed>eattr l@-le or temp1 ed>eattr l!-le
        !            32:                           ( dir addr dlen setup-packet-address )
        !            33:    temp1 swap TRUE            ( dir addr dlen ed-ptr setup-ptr TRUE )
        !            34: ;
        !            35: 
        !            36: 
        !            37: \ Allocate TD list
        !            38: 
        !            39: 
        !            40: : (td-prepare) ( dir addr dlen ed-ptr setup-ptr --
        !            41:                  dir FALSE | dir addr dlen ed-ptr setup-ptr td-head td-tail )
        !            42:    2 pick         ( dir addr dlen ed-ptr setup-ptr dlen )
        !            43:    temp2          ( dir addr dlen ed-ptr setup-ptr dlen MPS )
        !            44:    /mod           ( dir addr dlen ed-ptr setup-ptr rem quo )
        !            45:    swap 0<>   IF  ( dir addr dlen ed-ptr setup-ptr quo )
        !            46:       1+
        !            47:    THEN
        !            48:    2+
        !            49:    dup TO num-tds                ( dir addr dlen ed-ptr setup-ptr quo+2 )
        !            50:    allocate-td-list dup 0=  IF   ( dir addr dlen ed-ptr setup-ptr quo+2 )
        !            51:       2drop                      ( dir addr dlen ed-ptr setup-ptr )
        !            52:       drop                       ( dir addr dlen ed-ptr )
        !            53:       free-ed                    ( dir addr dlen )
        !            54:       2drop                      ( dir )
        !            55:       FALSE                      ( dir FALSE )
        !            56:       EXIT
        !            57:    THEN TRUE
        !            58: ;
        !            59: 
        !            60: 
        !            61: \ Fill in the ED structure completely.
        !            62: 
        !            63: 
        !            64: : (td-ready)  ( dir addr dlen ed-ptr setup-ptr td-head td-tail -- )
        !            65:               ( dir addr dlen ed-ptr setup-ptr )
        !            66:    3 pick     ( dir addr dlen ed-ptr setup-ptr td-head td-tail ed-ptr )
        !            67:    tuck       ( dir addr dlen ed-ptr setup-ptr td-head ed-ptr td-tail ed-ptr )
        !            68:    ed>tdqtp l!-le            ( dir addr dlen ed-ptr setup-ptr td-head ed-ptr )
        !            69:    ed>tdqhp l!-le            ( dir addr dlen ed-ptr setup-ptr )
        !            70:    over ed>ned 0 swap l!-le  ( dir addr dlen ed-ptr setup-ptr )
        !            71: ;
        !            72: 
        !            73: 
        !            74: \ Initialize the HEAD and TAIL TDs for SETUP and
        !            75: \ STATUS phase respectively.
        !            76: 
        !            77: 
        !            78: : (td-setup-status) ( dir addr dlen ed-ptr setup-ptr -- dir addr dlen ed-ptr )
        !            79:    over ed>tdqhp l@-le             ( dir addr dlen ed-ptr setup-ptr td-head )
        !            80:    dup zero-out-a-td-except-link   ( dir addr dlen ed-ptr setup-ptr td-head )
        !            81:    dup td>tattr DATA0-TOGGLE CC-FRESH-TD or swap l!-le
        !            82:                                    ( dir addr dlen ed-ptr setup-ptr td-head )
        !            83:    2dup td>cbptr l!-le             ( dir addr dlen ed-ptr setup-ptr td-head )
        !            84:    2dup td>bfrend swap STD-REQUEST-SETUP-SIZE 1- + swap l!-le
        !            85:                                    ( dir addr dlen ed-ptr setup-ptr td-head )
        !            86:    2drop                           ( dir addr dlen ed-ptr )
        !            87: ;
        !            88: 
        !            89: \ Initialize the TD TAIL pointer.
        !            90: 
        !            91: 
        !            92: : (td-tailpointer) ( dir addr dlen ed-ptr -- dir addr dlen ed-ptr )
        !            93:    dup ed>tdqtp l@-le              ( dir addr dlen ed-ptr td-tail )
        !            94:    dup zero-out-a-td-except-link   ( dir addr dlen ed-ptr td-tail )
        !            95:    dup td>tattr dup l@-le DATA1-TOGGLE CC-FRESH-TD or or swap l!-le
        !            96:                                    ( dir addr dlen ed-ptr td-tail )
        !            97:    4 pick 0=                       ( dir addr dlen ed-ptr td-tail flag )
        !            98:    3 pick 0<>                      ( dir addr dlen ed-ptr td-tail flag flag )
        !            99:    and   IF                        ( dir addr dlen ed-ptr td-tail )
        !           100:       dup td>tattr dup l@-le TD-DP-OUT or swap l!-le
        !           101:                                    ( dir addr dlen ed-ptr td-tail )
        !           102:    ELSE
        !           103:       dup td>tattr dup l@-le TD-DP-IN or swap l!-le
        !           104:                                   ( dir addr dlen ed-ptr td-tail )
        !           105:    THEN
        !           106:    drop                           ( dir addr dlen ed-ptr )
        !           107: ;
        !           108: 
        !           109: \  Initialize the Data TDs.
        !           110: 
        !           111: 
        !           112: : (td-data) ( dir addr dlen ed-ptr --  ed-ptr )
        !           113:    -rot             ( dir ed-ptr addr dlen )
        !           114:    dup 0<>  IF      ( dir ed-ptr addr dlen )
        !           115:       >r >r >r TO temp1 r> r> r> temp1 ( ed-ptr addr dlen dir )
        !           116:       3 pick                       ( ed-ptr addr dlen dir ed-ptr )
        !           117:       ed>tdqhp l@-le td>ntd l@-le   ( ed-ptr addr dlen dir td-datahead )
        !           118:       4 pick                      ( ed-ptr addr dlen dir td-datahead ed-ptr )
        !           119:       td>tattr l@-le 10 rshift ( ed-ptr addr dlen dir td-head-data MPS )
        !           120:       swap                         ( ed-ptr addr dlen dir MPS td-head-data )
        !           121:       >r >r >r >r >r 1 r> r> r> r> r>
        !           122:                                    ( ed-ptr 1 addr dlen dir MPS td-head-data )
        !           123:       >r >r 0=  IF                 ( ed-ptr 1 addr dlen dir )
        !           124:          OHCI-DP-IN                ( ed-ptr 1 addr dlen dir  OHCI-DP-IN )
        !           125:       ELSE
        !           126:          OHCI-DP-OUT               ( ed-ptr 1 addr dlen dir  OHCI-DP-OUT )
        !           127:       THEN
        !           128:       r> r>               ( ed-ptr 1 addr dlen dir  OHCI-DP- MPS td-head-data )
        !           129:       fill-TD-list
        !           130:    ELSE
        !           131:       2drop nip           ( ed-ptr )
        !           132:    THEN
        !           133: ;
        !           134: 
        !           135: 
        !           136: \ Program the HC with the ed-ptr value and wait for status to
        !           137: \ from the HC.
        !           138: \ Free the ED and TDs associated with it.
        !           139: \ PENDING: Above said.
        !           140: 
        !           141: 10 CONSTANT max-retire-td
        !           142: 
        !           143: : (transfer-wait-for-doneq)  ( ed-ptr -- TRUE | FALSE )
        !           144:    dup                               ( ed-ptr ed-ptr )
        !           145:    hcctrhead rl!-le                  ( ed-ptr )
        !           146:    HC-enable-control-list-processing ( ed-ptr )
        !           147:    0 TO td-retire-count              ( ed-ptr )
        !           148:    0 TO poll-timer                   ( ed-ptr )
        !           149:    BEGIN
        !           150:       td-retire-count num-tds <>     ( ed-ptr TRUE | FALSE )
        !           151:       poll-timer max-retire-td < and       ( ed-ptr TRUE | FALSE )
        !           152:       WHILE
        !           153:       (HC-CHECK-WDH)                                      ( ed-ptr )
        !           154:       IF
        !           155:          hchccadneq l@-le find-td-list-tail-and-size nip ( ed-ptr n )
        !           156:          td-retire-count + TO td-retire-count             ( ed-ptr )
        !           157:          hchccadneq l@-le dup              ( ed-ptr done-td done-td )
        !           158:          (td-list-status)                  ( ed-ptr done-td failed-td CCcode )
        !           159:          IF
        !           160:             \ keep condition code of TD on return stack
        !           161:             dup >r
        !           162:             s" (transfer-wait-for-doneq: USB device communication error."
        !           163:             usb-debug-print                 ( ed-ptr done-td failed-td CCcode R: CCcode )
        !           164:             dup 4 = swap dup 5 = rot or     ( ed-ptr done-td failed-td CCcode R: CCcode )
        !           165:             IF
        !           166:                 max-retire-td TO poll-timer ( ed-ptr done-td failed-td CCcode R: CCcode )
        !           167:             THEN
        !           168:             ( ed-ptr done-td failed-td CCcode R: CCcode )
        !           169:             usb-debug-flag
        !           170:             IF
        !           171:                s" CC code ->" type . cr
        !           172:                s" Failing TD contents:" type cr display-td
        !           173:             ELSE
        !           174:                2drop
        !           175:             THEN                           ( ed-ptr done-td R: CCcode )
        !           176:             controlxfer-cmd @ GET-MAX-LUN = r> 4 = and
        !           177:             IF
        !           178:                s" (transfer-wait-for-doneq): GET-MAX-LUN ControlXfer STALLed"
        !           179:                usb-debug-print
        !           180:                \ Condition Code = 4 means that the device does not support multiple LUNS
        !           181:                \ see USB Massbulk 1.0 Standard
        !           182:             ELSE
        !           183:                drop
        !           184:                5030 error" (USB) Device communication error."
        !           185:                ABORT
        !           186:                \ FIXME: ABORTing here might leave the HC in an unusable state.
        !           187:                \        We should maybe rather ABORT at the end of this Forth
        !           188:                \        word, when clean-up has been done (or not ABORT at all)
        !           189:             THEN
        !           190:          THEN                              ( ed-ptr done-td )
        !           191:          (free-td-list)                    ( ed-ptr )
        !           192:          0 hchccadneq l!-le                ( ed-ptr )
        !           193:          (HC-ACK-WDH) \ TDs were written to DOne queue. ACK the HC.
        !           194:       THEN
        !           195:       poll-timer 1+ TO poll-timer
        !           196:       4 ms              \ longer  1 ms
        !           197:    REPEAT                                  ( ed-ptr )
        !           198:    disable-control-list-processing         ( ed-ptr )
        !           199:    td-retire-count num-tds <>              ( ed-ptr )
        !           200:    IF
        !           201:       dup display-descriptors              ( ed-ptr )
        !           202:       s" maximum of retire " usb-debug-print                                                
        !           203:    THEN
        !           204:    free-ed
        !           205:    td-retire-count num-tds <>
        !           206:    IF
        !           207:       FALSE                                ( FALSE )
        !           208:    ELSE
        !           209:       TRUE                                 ( TRUE )
        !           210:    THEN
        !           211: ;
        !           212: 
        !           213: 
        !           214: \ COLON DEFINITION: controlxfer
        !           215: \                     INTERFACE FUNCTION
        !           216: 
        !           217: \ ARGUMENTS:
        !           218: \ (from the bottom OF stack)
        !           219: \ 1. dir -- This is the direction OF data transfer associated with
        !           220: \           the DATA STAGE OF the control xfer.
        !           221: \           If there is no data transfer (argument dlen is zero)
        !           222: \           THEN this argument DOes not matter, nonethless it has
        !           223: \           to be passed.
        !           224: \           A "0" represents an IN and "1" represents an "OUT".
        !           225: \ 2. addr -- If therez a data stage associated with the transfer,
        !           226: \            THEN, this argument holds the address OF the data buffer
        !           227: \ 3. dlen -- This arg holds the length OF the data buffer discussed
        !           228: \            in previous step (addr)
        !           229: \ 4. setup-packet -- This holds the pointer to the setup packet that
        !           230: \                    will be transmitted during the SETUP stage OF
        !           231: \                    the control xfer. The function assumes the length
        !           232: \                    OF the status packet to be 8 bytes.
        !           233: \ 5. MPS -- This is the MAX PACKET SIZE OF the endpoint.
        !           234: \ 6. ep-fun -- This is the 11-bit value that holds the Endpoint and
        !           235: \              the function address. bit 7 to bit 10 holds the Endpoint
        !           236: \              address. Bits 0 to Bit 6 holds the Function Address.
        !           237: \              The BIT numbering followed : The left most bit is referred
        !           238: \              as bit 0. (not the one followed by PPC)
        !           239: \              Bit 13 must be set for low-speed devices.
        !           240: 
        !           241: \ RETURN VALUE:
        !           242: \ Returns TRUE | FALSE depending on the success OF the transaction.
        !           243: 
        !           244: \ ASSUMPTIONS:
        !           245: \ 1. Function assumes that the setup packet is 8-bytes in length.
        !           246: \    If in future, IF we need to add a new argument, we need to change
        !           247: \    the function in lot OF places.
        !           248: 
        !           249: \ RISKS:
        !           250: \ 1. If for some reason, the USB controller DOes not retire all the TDs
        !           251: \    THEN, the status checking part OF this "word" can spin forever.
        !           252: 
        !           253: 
        !           254: : controlxfer ( dir addr dlen setup-packet MPS ep-fun -- TRUE | FALSE )
        !           255:    2 pick @ controlxfer-cmd !
        !           256:    (ed-prepare)       ( FALSE | dir addr dlen ed-ptr setup-ptr  )
        !           257:    invert IF FALSE EXIT THEN
        !           258:    (td-prepare)       ( pt ed-type toggle buffer length mps head )
        !           259:    invert IF FALSE EXIT THEN
        !           260:    (td-ready)         ( dir addr dlen ed-ptr setup-ptr )
        !           261:    (td-setup-status)  ( dir addr dlen ed-ptr )
        !           262:    (td-tailpointer)   ( dir addr dlen ed-ptr )
        !           263:    (td-data)          ( ed-ptr )
        !           264: 
        !           265: 
        !           266:    \ FIXME:
        !           267:    \ Clear the TAIL pointer in ED. This has got sthg to DO with how
        !           268:    \ the HC finds an EMPTY queue condition. Refer spec.
        !           269: 
        !           270: 
        !           271:    dup ed>tdqtp l@-le TO saved-tail    ( ed-ptr )
        !           272:    dup ed>tdqtp 0 swap l!-le           ( ed-ptr )
        !           273:    (transfer-wait-for-doneq)           ( TRUE | FALSE )
        !           274: ;
        !           275: 
        !           276: 0201000000000000 CONSTANT CLEARHALTFEATURE
        !           277: 0 VALUE endpt-num
        !           278: 0 VALUE usb-addr-contr-req
        !           279: : control-std-clear-feature ( endpoint-nr usb-addr -- TRUE|FALSE )
        !           280:    TO usb-addr-contr-req                        \ usb address
        !           281:    TO endpt-num                                 \ endpoint number
        !           282:    CLEARHALTFEATURE setup-packet !
        !           283:    endpt-num setup-packet 4 + c!                \ endpoint number
        !           284:    0 0 0 setup-packet DEFAULT-CONTROL-MPS usb-addr-contr-req controlxfer
        !           285:    ( TRUE|FALSE )
        !           286: ;  
        !           287: 
        !           288: \ It resets the usb bulk-device
        !           289: 21FF000000000000 CONSTANT BULK-RESET
        !           290: : control-std-bulk-reset ( usb-addr -- TRUE|FALSE )
        !           291:   TO usb-addr-contr-req
        !           292:   BULK-RESET setup-packet !
        !           293:   0 0 0 setup-packet DEFAULT-CONTROL-MPS usb-addr-contr-req controlxfer
        !           294:   ( TRUE|FALSE )
        !           295: ;
        !           296: 
        !           297: : bulk-reset-recovery-procedure ( bulk-out-endp bulk-in-endp usb-addr -- )
        !           298:     >r                                          ( bulk-out-endp bulk-in-endp R: usb-addr )
        !           299:     \ perform a bulk reset
        !           300:     r@ control-std-bulk-reset
        !           301:     IF s" bulk reset OK" 
        !           302:     ELSE s" bulk reset failed" 
        !           303:     THEN usb-debug-print
        !           304:     
        !           305:     \ clear bulk-in endpoint                    ( bulk-out-endp bulk-in-endp R: usb-addr )
        !           306:     80 or r@ control-std-clear-feature
        !           307:     IF s" control-std-clear IN endpoint OK" 
        !           308:     ELSE s" control-std-clear-IN endpoint failed" 
        !           309:     THEN usb-debug-print
        !           310: 
        !           311:     \ clear bulk-out endpoint                   ( bulk-out-endp R: usb-addr )
        !           312:     r@ control-std-clear-feature
        !           313:     IF s" control-std-clear OUT endpoint OK" 
        !           314:     ELSE s" control-std-clear-OUT endpoint failed" 
        !           315:     THEN usb-debug-print
        !           316:     r> drop
        !           317: ;
        !           318: 
        !           319: 0 VALUE saved-rw-ed
        !           320: 0 VALUE num-rw-tds
        !           321: 0 VALUE num-rw-retired-tds
        !           322: 0 VALUE saved-rw-start-toggle
        !           323: 0 VALUE saved-list-type
        !           324: 
        !           325: \ Allocate an ED and populate what you can.
        !           326: 
        !           327: 
        !           328: : (ed-prepare-rw)
        !           329:    ( pt ed-type toggle buffer length mps address ed-ptr --
        !           330:       FALSE | pt ed-type toggle buffer length mps )
        !           331:    allocate-ed dup 0=  IF
        !           332:    ( pt ed-type toggle buffer length mps address ed-ptr )
        !           333:       drop 2drop 2drop 2drop drop
        !           334:       saved-rw-start-toggle FALSE EXIT  ( toggle FALSE )
        !           335:    THEN
        !           336:    TO saved-rw-ed             ( pt ed-type toggle buffer length mps address )
        !           337:    saved-rw-ed zero-out-an-ed-except-link
        !           338:                               ( pt ed-type toggle buffer length mps address )
        !           339:    saved-rw-ed ed>eattr l!-le   ( pt ed-type toggle buffer length mps )
        !           340:    dup 10 lshift saved-rw-ed ed>eattr l@-le or
        !           341:                               ( pt ed-type toggle buffer length mps mps~ )
        !           342:    saved-rw-ed ed>eattr l!-le TRUE  ( pt ed-type toggle buffer length mps TRUE )
        !           343: ;
        !           344: 
        !           345: 
        !           346: \  Allocate TD List
        !           347: 
        !           348: 
        !           349: : (td-prepare-rw)
        !           350:    ( pt ed-type toggle buffer length mps --
        !           351:      FALSE | pt ed-type toggle buffer length mps head )
        !           352:    2dup              ( pt ed-type toggle buffer length mps  length mps )
        !           353:    /mod              ( pt ed-type toggle buffer length mps num-tds rem )
        !           354:    swap 0<> IF       ( pt ed-type toggle buffer length mps num-tds )
        !           355:       1+             ( pt ed-type toggle buffer length mps num-tds+1 )
        !           356:    THEN
        !           357:    dup TO num-rw-tds ( pt ed-type toggle buffer length mps num-tds )
        !           358:    allocate-td-list  ( pt ed-type toggle buffer length mps head tail )
        !           359:    dup 0=  IF
        !           360:       2drop 2drop 2drop 2drop
        !           361:       saved-rw-ed free-ed
        !           362:       ." rw-endpoint: TD list allocation failed" cr
        !           363:       saved-rw-start-toggle FALSE   ( FALSE )
        !           364:       EXIT
        !           365:    THEN
        !           366:    drop  TRUE         ( pt ed-type toggle buffer length mps head TRUE )
        !           367: ;
        !           368: 
        !           369: 
        !           370: \ Populate TD list with data buffers and toggle info.
        !           371: 
        !           372: 
        !           373: : (td-data-rw)
        !           374:    ( pt ed-type toggle buffer length mps head -- FALSE | pt et head )
        !           375:    6 pick                    ( pt ed-type toggle buffer length mps head  pt )
        !           376:    FALSE TO case-failed  CASE
        !           377:       0   OF OHCI-DP-IN    ENDOF
        !           378:       1   OF OHCI-DP-OUT   ENDOF
        !           379:       2   OF OHCI-DP-SETUP ENDOF
        !           380:       dup OF TRUE TO case-failed
        !           381:       ." rw-endpoint: Invalid Packet Type!" cr
        !           382:       ENDOF
        !           383:    ENDCASE                   ( pt ed-type toggle buffer length mps head dp )
        !           384:    case-failed  IF
        !           385:       saved-rw-ed free-ed    ( pt ed-type toggle buffer length mps head dp )
        !           386:       drop (free-td-list)         ( pt ed-type toggle buffer length mps head )
        !           387:       2drop 2drop 2drop
        !           388:       saved-rw-start-toggle FALSE ( FALSE )
        !           389:       EXIT                        ( FALSE )
        !           390:    THEN
        !           391:    -rot                      ( pt ed-type toggle buffer length dp mps head )
        !           392:    dup >r                      ( pt ed-type toggle buffer length dp mps head )
        !           393:    fill-TD-list r>  TRUE      ( pt et head TRUE )
        !           394: ;
        !           395: 
        !           396: 
        !           397: \ Enqueue the ED with the appropriate list
        !           398: 
        !           399: 
        !           400: : (ed-ready-rw)  ( pt et  -- - | toggle FALSE )
        !           401:    nip           ( et )
        !           402:    FALSE TO case-failed  CASE
        !           403:       0   OF \ Control List. Queue the ED to control list
        !           404:       0 TO saved-list-type
        !           405:       saved-rw-ed hcctrhead rl!-le
        !           406:       HC-enable-control-list-processing
        !           407:       ENDOF
        !           408:       1   OF \ Bulk List. Queue the ED to bulk list
        !           409:       1 TO saved-list-type
        !           410:       saved-rw-ed hcbulkhead rl!-le
        !           411:       HC-enable-bulk-list-processing
        !           412:       ENDOF
        !           413:       2   OF \ Interrupt List.
        !           414:       2 TO saved-list-type
        !           415:       saved-rw-ed hchccareg rl@-le rl!-le
        !           416:       HC-enable-interrupt-list-processing
        !           417:       ENDOF
        !           418:       dup OF
        !           419:       saved-rw-ed ed>tdqhp l@-le (free-td-list)
        !           420:       saved-rw-ed free-ed
        !           421:       TRUE TO case-failed
        !           422:       ENDOF
        !           423:    ENDCASE
        !           424:    case-failed  IF
        !           425:       saved-rw-start-toggle FALSE ( toggle FALSE )
        !           426:       EXIT
        !           427:    THEN
        !           428:    TRUE                           ( TRUE )
        !           429: ;
        !           430: 
        !           431: \  Wait for TDs to return to the Done Q.
        !           432: 
        !           433: : (wait-td-retire) ( -- )
        !           434:    0 TO num-rw-retired-tds
        !           435:    FALSE TO while-failed
        !           436:    BEGIN
        !           437:       num-rw-retired-tds num-rw-tds <           ( TRUE | FALSE )
        !           438:       while-failed FALSE =  and                 ( TRUE | FALSE )
        !           439:       WHILE
        !           440:       d# 5000 (wait-for-done-q)                  ( TD-list TRUE|FALSE )
        !           441:       IF
        !           442:          dup find-td-list-tail-and-size nip         ( td-list size )
        !           443:          num-rw-retired-tds + TO num-rw-retired-tds ( td-list )
        !           444:          dup (td-list-status)                   ( td-list failed-TD CC )
        !           445:          IF
        !           446:             dup 4 =
        !           447:             IF
        !           448:                saved-list-type
        !           449:                CASE
        !           450:                   0 OF
        !           451:                               0 0 control-std-clear-feature
        !           452:                               s" clear feature " usb-debug-print
        !           453:                   ENDOF
        !           454:                   1 OF                             \ clean bulk stalled
        !           455:                      s" clear bulk when stalled " usb-debug-print
        !           456:                               disable-bulk-list-processing   \ disable procesing
        !           457:                      saved-rw-ed ed>eattr l@-le dup \ extract
        !           458:                      780 and 7 rshift 80 or         \ endpoint and
        !           459:                      swap 7f and                    \ usb addr
        !           460:                      control-std-clear-feature
        !           461:                            ENDOF
        !           462:                   2 OF
        !           463:                               0 saved-rw-ed ed>eattr l@-le
        !           464:                      control-std-clear-feature
        !           465:                            ENDOF
        !           466:                            dup OF
        !           467:                               s" unknown status " usb-debug-print
        !           468:                            ENDOF
        !           469:                ENDCASE
        !           470:             ELSE                             ( td-list failed-TD CC )
        !           471:                ."  TD failed  " 5b emit .s 5d emit cr
        !           472:                5040 error" (USB) device transaction error (wait-td-retire)."
        !           473:                ABORT
        !           474:             THEN
        !           475:             2drop drop
        !           476:             TRUE TO while-failed                \ transaction failed
        !           477:             NEXT-TD 0<>                         \ clean the TD if we
        !           478:             IF
        !           479:                NEXT-TD (free-td-list)           \ had a stalled
        !           480:              THEN
        !           481:          THEN
        !           482:          (free-td-list)
        !           483:       ELSE
        !           484:          drop                                   \ drop td-list pointer
        !           485:          scan-time? IF 2e emit THEN             \ show proceeding dots
        !           486:          TRUE TO while-failed
        !           487:              s" time out wait for done" usb-debug-print
        !           488:              20 ms     \ wait for bad device
        !           489:       THEN
        !           490:    REPEAT
        !           491: ;
        !           492: 
        !           493: 
        !           494: \ Process retired TDs
        !           495: 
        !           496: 
        !           497: : (process-retired-td)   ( -- TRUE | FALSE )
        !           498:    saved-list-type  CASE
        !           499:       0 OF disable-control-list-processing ENDOF
        !           500:       1 OF disable-bulk-list-processing ENDOF
        !           501:       2 OF disable-interrupt-list-processing ENDOF
        !           502:    ENDCASE
        !           503:    saved-rw-ed ed>tdqhp l@-le 2 and 0<> IF 
        !           504:       1 
        !           505:       s" retired 1" usb-debug-print
        !           506:    ELSE
        !           507:       0 
        !           508:       s" retired 0" usb-debug-print
        !           509:    THEN
        !           510:    \ s" retired " usb-debug-print-val
        !           511:    WHILE-failed   IF
        !           512:       FALSE           ( FALSE )
        !           513:    ELSE
        !           514:       TRUE            ( TRUE )
        !           515:    THEN
        !           516:    saved-rw-ed free-ed
        !           517: ;
        !           518: 
        !           519: 
        !           520: \ (DO-rw-endpoint): T1 12 80 0 0chis method is an privately visible function
        !           521: \                  to be used by the "rw-endpoint" the required
        !           522: \                  number OF times based on the actual length
        !           523: \                  to be transferred
        !           524: 
        !           525: \ Arguments:
        !           526: \ pt: Packet type
        !           527: \     0 -> IN
        !           528: \     1 -> OUT
        !           529: \     2 -> SETUP
        !           530: \ et: Endpoint type
        !           531: \     0 -> Control
        !           532: \     1 -> Bulk
        !           533: \ toggle: Starting toggle for this transfer
        !           534: \ buffer length: Data buffer associated with the transfer limited
        !           535: \     accordingly by the "rw-endpoint" method to the
        !           536: \     value OF max packet size
        !           537: \ mps: Max Packet Size.
        !           538: \ address: Address OF endpoint. 11-bit address. The lower 7-bits represent
        !           539: \          the USB addres and the upper 4-bits represent the Endpoint
        !           540: \          number.
        !           541: 
        !           542: 
        !           543: 
        !           544: : (do-rw-endpoint)
        !           545:    ( pt ed-type toggle buffer length mps address -- toggle TRUE|toggle FALSE )
        !           546:    4 pick              ( pt ed-type toggle buffer length mps address toggle )
        !           547:    TO saved-rw-start-toggle ( pt ed-type toggle buffer length mps address )
        !           548:    (ed-prepare-rw)     ( FALSE | pt ed-type toggle buffer length mps )
        !           549:     invert IF FALSE EXIT THEN
        !           550:    (td-prepare-rw)     ( FALSE | pt ed-type toggle buffer length mps head )
        !           551:    invert IF FALSE EXIT THEN
        !           552:    (td-data-rw)        ( FALSE | pt et head )
        !           553:    invert IF FALSE EXIT THEN
        !           554:    saved-rw-ed ed>tdqhp l!-le ( pt et )
        !           555:    saved-rw-ed ed>tdqhp l@-le td>ntd l@-le TO NEXT-TD \ save for a stalled
        !           556:    (ed-ready-rw)
        !           557:    invert IF FALSE EXIT THEN
        !           558:    (wait-td-retire)
        !           559:    (process-retired-td)         ( TRUE | FALSE )
        !           560: ;
        !           561: 
        !           562: 
        !           563: \ rw-endpoint: The method is an externally visible method to be exported
        !           564: \             to the child nodes. It uses the internal method
        !           565: \             "(DO-rw-endpoint)", the required number OF times based on the
        !           566: \             actual length OF transfer, so that the limitataion OF MAX-TDS
        !           567: \             DO not hinder the transfer.
        !           568: 
        !           569: \ Arguments:
        !           570: \ pt: Packet type
        !           571: \     0 -> IN
        !           572: \     1 -> OUT
        !           573: \     2 -> SETUP
        !           574: \ et: Endpoint type
        !           575: \     0 -> Control
        !           576: \     1 -> Bulk
        !           577: \ toggle: Starting toggle for this transfer
        !           578: \ buffer length: Data buffer associated with the transfer
        !           579: \ mps: Max Packet Size.
        !           580: \ address: Address OF endpoint. 11-bit address. The lower 7-bits represent
        !           581: \          the USB addres and the upper 4-bits represent the Endpoint
        !           582: \          number.
        !           583: 
        !           584: 
        !           585: 0 VALUE transfer-len
        !           586: 0 VALUE mps-current
        !           587: 0 VALUE addr-current
        !           588: 0 VALUE usb-addr
        !           589: 0 VALUE toggle-current
        !           590: 0 VALUE type-current
        !           591: 0 VALUE pt-current
        !           592: 0 VALUE read-status
        !           593: 0 VALUE counter
        !           594: 0 VALUE residue
        !           595: 
        !           596: 
        !           597: : rw-endpoint
        !           598:    ( pt ed-type toggle buffer length mps address -- )
        !           599:    ( toggle TRUE |toggle FALSE )
        !           600: 
        !           601:    \ a single transfer descriptor can point to a buffer OF
        !           602:    \ 8192 bytes a block on the CDROM has 2048 bytes
        !           603:    \ but a single transfer is constrained by the MPS
        !           604: 
        !           605:    2 pick TO transfer-len  ( pt ed-type toggle buffer length mps address )
        !           606:    1 pick TO mps-current   ( pt ed-type toggle buffer length mps address )
        !           607:    TRUE TO read-status     ( pt ed-type toggle buffer length mps address )
        !           608:    transfer-len mps-current num-free-tds * <=  IF
        !           609:       (do-rw-endpoint)     ( toggle TRUE | toggle FALSE )
        !           610:       TO read-status       ( toggle )
        !           611:       TO toggle-current
        !           612:    ELSE
        !           613:       TO usb-addr          ( pt ed-type toggle buffer length mps )
        !           614:       2drop                ( pt ed-type toggle buffer )
        !           615:       TO addr-current      ( pt ed-type toggle )
        !           616:       TO toggle-current    ( pt ed-type )
        !           617:       TO type-current      ( pt )
        !           618:       TO pt-current
        !           619:       transfer-len mps-current num-free-tds * /mod  ( residue count )
        !           620:                            ( remainder=residue quotient=count )
        !           621:       TO counter           ( residue )
        !           622:       TO residue
        !           623:       mps-current num-free-tds * TO transfer-len   BEGIN
        !           624:          counter 0 >       ( TRUE | FALSE )
        !           625:          read-status TRUE = and   ( TRUE | FALSE )
        !           626:       WHILE
        !           627:          pt-current type-current toggle-current ( pt ed-type toggle )
        !           628:          addr-current transfer-len  ( pt ed-type toggle buffer length )
        !           629:          mps-current                ( pt ed-type toggle buffer length mps )
        !           630:          usb-addr (do-rw-endpoint)  ( toggle TRUE | toggle FALSE )
        !           631:          TO read-status             ( toggle )
        !           632:          TO toggle-current
        !           633:          addr-current transfer-len + TO addr-current
        !           634:          counter 1- TO counter
        !           635:       REPEAT
        !           636:       residue 0<>                    ( TRUE |FALSE )
        !           637:       read-status TRUE = and IF
        !           638:          residue TO transfer-len
        !           639:          pt-current type-current toggle-current ( pt ed-type toggle )
        !           640:          addr-current transfer-len   ( pt ed-type toggle buffer length )
        !           641:          mps-current                 ( pt ed-type toggle buffer length mps )
        !           642:          usb-addr (do-rw-endpoint)   ( toggle TRUE | toggle FALSE )
        !           643:          TO read-status
        !           644:          TO toggle-current
        !           645:       THEN
        !           646:    THEN
        !           647:    read-status invert  IF
        !           648:    THEN
        !           649:    toggle-current                    ( toggle )
        !           650:    read-status                       ( TRUE | FALSE )
        !           651: ;

unix.superglobalmegacorp.com

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