|
|
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: ;
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.