|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * The contents of this file constitute Original Code as defined in and ! 7: * are subject to the Apple Public Source License Version 1.1 (the ! 8: * "License"). You may not use this file except in compliance with the ! 9: * License. Please obtain a copy of the License at ! 10: * http://www.apple.com/publicsource and read it before using this file. ! 11: * ! 12: * This Original Code and all software distributed under the License are ! 13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 17: * License for the specific language governing rights and limitations ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: /* ! 23: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 24: * ! 25: * HISTORY ! 26: * ! 27: */ ! 28: ! 29: #include <IOKit/firewire/IOFWDCLTranslator.h> ! 30: ! 31: //////////////////////////////////////////////////////////////////////////////// ! 32: // ! 33: // FWDCLReceivePacketStart ! 34: // ! 35: // This routine runs a DCL receive packet start command. ! 36: // ! 37: ! 38: static void DCLReceivePacketStart( ! 39: DCLCommandPtr *ppCurrentDCLCommand, ! 40: UInt32 packetHeader, ! 41: UInt8 * *pPacketBuffer, ! 42: UInt32 *pPacketSize, ! 43: bool *pGetNextPacket) ! 44: { ! 45: DCLTransferPacketPtr pDCLTransferPacket; ! 46: UInt8 * transferBuffer; ! 47: UInt8 * packetBuffer; ! 48: SInt32 transferSize, packetSize; ! 49: ! 50: // Recast DCL command. ! 51: pDCLTransferPacket = (DCLTransferPacketPtr) *ppCurrentDCLCommand; ! 52: ! 53: // Get some parameters. ! 54: transferBuffer = (UInt8 *)pDCLTransferPacket->buffer; ! 55: transferSize = pDCLTransferPacket->size - sizeof (UInt32); ! 56: packetSize = *pPacketSize; ! 57: if (transferSize > packetSize) ! 58: transferSize = packetSize; ! 59: packetBuffer = *pPacketBuffer; ! 60: ! 61: // Transfer the packet data. ! 62: *((UInt32 *) transferBuffer) = packetHeader; ! 63: transferBuffer += sizeof (UInt32); ! 64: if (transferSize > 0) { ! 65: bcopy (packetBuffer, transferBuffer, transferSize); ! 66: packetSize -= transferSize; ! 67: packetBuffer += transferSize; ! 68: } ! 69: ! 70: // Check if we need another packet. ! 71: *pGetNextPacket = true; ! 72: if (pDCLTransferPacket->pNextDCLCommand != NULL) ! 73: { ! 74: if ((pDCLTransferPacket->pNextDCLCommand->opcode & ~kFWDCLOpFlagMask) == ! 75: kDCLReceivePacketOp) ! 76: { ! 77: *pGetNextPacket = false; ! 78: } ! 79: } ! 80: ! 81: // Update parameters. ! 82: *ppCurrentDCLCommand = pDCLTransferPacket->pNextDCLCommand; ! 83: *pPacketBuffer = packetBuffer; ! 84: *pPacketSize = packetSize; ! 85: } ! 86: ! 87: ! 88: //////////////////////////////////////////////////////////////////////////////// ! 89: // ! 90: // DCLReceivePacket ! 91: // ! 92: // This routine runs a DCL receive packet command. ! 93: // ! 94: ! 95: static void DCLReceivePacket( ! 96: DCLCommandPtr *ppCurrentDCLCommand, ! 97: UInt32 packetHeader, ! 98: UInt8 * *pPacketBuffer, ! 99: UInt32 *pPacketSize, ! 100: bool *pGetNextPacket) ! 101: { ! 102: DCLTransferPacketPtr pDCLTransferPacket; ! 103: UInt8 * transferBuffer; ! 104: UInt8 * packetBuffer; ! 105: UInt32 transferSize, packetSize; ! 106: ! 107: // Recast DCL command. ! 108: pDCLTransferPacket = (DCLTransferPacketPtr) *ppCurrentDCLCommand; ! 109: ! 110: // Get some parameters. ! 111: transferBuffer = (UInt8 *)pDCLTransferPacket->buffer; ! 112: transferSize = pDCLTransferPacket->size; ! 113: packetSize = *pPacketSize; ! 114: if (transferSize > packetSize) ! 115: transferSize = packetSize; ! 116: packetBuffer = *pPacketBuffer; ! 117: ! 118: // Transfer the packet data. ! 119: if (transferSize > 0) ! 120: { ! 121: bcopy (packetBuffer, transferBuffer, transferSize); ! 122: packetSize -= transferSize; ! 123: packetBuffer += transferSize; ! 124: } ! 125: ! 126: // Check if we need another packet. ! 127: *pGetNextPacket = true; ! 128: if (pDCLTransferPacket->pNextDCLCommand != NULL) ! 129: { ! 130: if ((pDCLTransferPacket->pNextDCLCommand->opcode & ~kFWDCLOpFlagMask) == ! 131: kDCLReceivePacketOp) ! 132: { ! 133: *pGetNextPacket = false; ! 134: } ! 135: } ! 136: ! 137: // Update parameters. ! 138: *ppCurrentDCLCommand = pDCLTransferPacket->pNextDCLCommand; ! 139: *pPacketBuffer = packetBuffer; ! 140: *pPacketSize = packetSize; ! 141: } ! 142: ! 143: ! 144: //////////////////////////////////////////////////////////////////////////////// ! 145: // ! 146: // FWDCLReceiveBuffer ! 147: // ! 148: // This routine runs a DCL receive buffer command. ! 149: //zzz should we include packet header? ! 150: //zzz should we clip off end of packet when buffer is filled? ! 151: // ! 152: ! 153: static void DCLReceiveBuffer( ! 154: DCLCommandPtr *ppCurrentDCLCommand, ! 155: UInt32 packetHeader, ! 156: UInt8 * *pPacketBuffer, ! 157: UInt32 *pPacketSize, ! 158: bool *pGetNextPacket) ! 159: { ! 160: DCLTransferBufferPtr pDCLTransferBuffer; ! 161: UInt8 * buffer; ! 162: UInt32 bufferOffset, bufferSize; ! 163: UInt32 bufferSizeLeft; ! 164: UInt8 * packetBuffer; ! 165: UInt32 packetSize; ! 166: UInt32 transferSize; ! 167: ! 168: // Recast current DCL command. ! 169: pDCLTransferBuffer = (DCLTransferBufferPtr) *ppCurrentDCLCommand; ! 170: ! 171: // Get some parameters. ! 172: buffer = (UInt8 *)pDCLTransferBuffer->buffer; ! 173: bufferOffset = pDCLTransferBuffer->bufferOffset; ! 174: bufferSize = pDCLTransferBuffer->size; ! 175: packetBuffer = *pPacketBuffer; ! 176: packetSize = *pPacketSize; ! 177: ! 178: // Compute size of transfer. ! 179: bufferSizeLeft = bufferSize - bufferOffset; ! 180: if (bufferSizeLeft > packetSize) ! 181: transferSize = packetSize; ! 182: else ! 183: transferSize = bufferSizeLeft; ! 184: ! 185: // Transfer the packet data. ! 186: if (transferSize > 0) ! 187: { ! 188: bcopy (packetBuffer, buffer + bufferOffset, transferSize); ! 189: ! 190: packetBuffer += transferSize; ! 191: packetSize -= transferSize; ! 192: bufferOffset += transferSize; ! 193: } ! 194: ! 195: // Check if we're done with this DCL or need another packet. ! 196: if (bufferOffset == bufferSize) ! 197: { ! 198: *ppCurrentDCLCommand = pDCLTransferBuffer->pNextDCLCommand; ! 199: *pGetNextPacket = false; ! 200: } ! 201: else ! 202: { ! 203: *pGetNextPacket = true; ! 204: } ! 205: ! 206: // Update parameters. ! 207: pDCLTransferBuffer->bufferOffset = bufferOffset; ! 208: *pPacketBuffer = packetBuffer; ! 209: *pPacketSize = packetSize; ! 210: } ! 211: ! 212: //////////////////////////////////////////////////////////////////////////////// ! 213: // ! 214: // DCLSendPacket ! 215: // ! 216: // This routine runs a DCL send packet command. ! 217: // ! 218: ! 219: static void DCLSendPacket( ! 220: DCLCommandPtr *ppCurrentDCLCommand, ! 221: UInt8 * *pPacketBuffer, ! 222: UInt32 *pPacketSize, ! 223: bool *pGetNextPacket) ! 224: { ! 225: DCLTransferPacketPtr pDCLTransferPacket; ! 226: UInt8 * transferBuffer; ! 227: UInt8 * packetBuffer; ! 228: UInt32 transferSize, packetSize; ! 229: ! 230: // Recast DCL command. ! 231: pDCLTransferPacket = (DCLTransferPacketPtr) *ppCurrentDCLCommand; ! 232: ! 233: // Get some parameters. ! 234: transferBuffer = (UInt8 *)pDCLTransferPacket->buffer; ! 235: transferSize = pDCLTransferPacket->size; ! 236: packetSize = *pPacketSize; ! 237: packetBuffer = *pPacketBuffer + packetSize; ! 238: ! 239: // Transfer the packet data. ! 240: bcopy (transferBuffer, packetBuffer, transferSize); ! 241: packetSize += transferSize; ! 242: ! 243: // Check if we need another packet. ! 244: *pGetNextPacket = true; ! 245: if (pDCLTransferPacket->pNextDCLCommand != NULL) ! 246: { ! 247: if ((pDCLTransferPacket->pNextDCLCommand->opcode & ~kFWDCLOpFlagMask) == ! 248: kDCLSendPacketOp) ! 249: { ! 250: *pGetNextPacket = false; ! 251: } ! 252: } ! 253: ! 254: // Update parameters. ! 255: *ppCurrentDCLCommand = pDCLTransferPacket->pNextDCLCommand; ! 256: *pPacketSize = packetSize; ! 257: } ! 258: ! 259: ! 260: //////////////////////////////////////////////////////////////////////////////// ! 261: // ! 262: // DCLSendBuffer ! 263: // ! 264: // This routine runs a DCL send buffer command. ! 265: //zzz should we clip off end of packet when buffer is emptied? ! 266: // ! 267: ! 268: static void DCLSendBuffer( ! 269: DCLCommandPtr *ppCurrentDCLCommand, ! 270: UInt8 * *pPacketBuffer, ! 271: UInt32 *pPacketSize, ! 272: bool *pGetNextPacket) ! 273: { ! 274: DCLTransferBufferPtr pDCLTransferBuffer; ! 275: UInt8 * buffer; ! 276: UInt32 bufferOffset, bufferSize; ! 277: UInt32 bufferSizeLeft; ! 278: UInt8 * packetBuffer; ! 279: UInt32 packetSize; ! 280: UInt32 transferPacketSize; ! 281: UInt32 transferSize; ! 282: ! 283: // Recast current DCL command. ! 284: pDCLTransferBuffer = (DCLTransferBufferPtr) *ppCurrentDCLCommand; ! 285: ! 286: // Get some parameters. ! 287: buffer = (UInt8 *)pDCLTransferBuffer->buffer; ! 288: bufferOffset = pDCLTransferBuffer->bufferOffset; ! 289: bufferSize = pDCLTransferBuffer->size; ! 290: packetSize = *pPacketSize; ! 291: packetBuffer = *pPacketBuffer + packetSize; ! 292: transferPacketSize = pDCLTransferBuffer->packetSize; ! 293: ! 294: // Compute size of transfer. ! 295: bufferSizeLeft = bufferSize - bufferOffset; ! 296: if (bufferSizeLeft > transferPacketSize) ! 297: transferSize = transferPacketSize; ! 298: else ! 299: transferSize = bufferSizeLeft; ! 300: ! 301: // Transfer the packet data. ! 302: if (transferSize > 0) ! 303: { ! 304: bcopy (buffer + bufferOffset, packetBuffer, transferSize); ! 305: ! 306: packetSize += transferSize; ! 307: bufferOffset += transferSize; ! 308: } ! 309: ! 310: // Check if we're done with this DCL or need another packet. ! 311: //zzz is this the best way to do this? ! 312: //zzz what if the next transfer command is a transfer packet command? ! 313: if (bufferOffset == bufferSize) ! 314: { ! 315: *ppCurrentDCLCommand = pDCLTransferBuffer->pNextDCLCommand; ! 316: *pGetNextPacket = false; ! 317: } ! 318: else ! 319: { ! 320: *pGetNextPacket = true; ! 321: } ! 322: ! 323: // Update parameters. ! 324: pDCLTransferBuffer->bufferOffset = bufferOffset; ! 325: *pPacketSize = packetSize; ! 326: } ! 327: ! 328: //////////////////////////////////////////////////////////////////////////////// ! 329: // ! 330: // FWRunTranslatedDCLEngine ! 331: // ! 332: // This routine runs the current DCL command using the given packet. It will ! 333: // update the current DCL command, packet buffer pointer, packet size, and will ! 334: // set get next packet to true if it needs another packet. ! 335: //zzz maybe a vector table would be nice ! 336: //zzz implement rest of DCL commands. ! 337: // ! 338: ! 339: static void RunListeningDCLEngine( ! 340: DCLCommandPtr *ppCurrentDCLCommand, ! 341: UInt32 packetHeader, ! 342: UInt8 * *pPacketBuffer, ! 343: UInt32 *pPacketSize, ! 344: bool *pGetNextPacket) ! 345: { ! 346: DCLCommandPtr pCurrentDCLCommand; ! 347: DCLCallProcPtr pDCLCallProc; ! 348: DCLJumpPtr pDCLJump; ! 349: ! 350: // Run the current DCL command. ! 351: pCurrentDCLCommand = *ppCurrentDCLCommand; ! 352: switch (pCurrentDCLCommand->opcode & ~kFWDCLOpFlagMask) ! 353: { ! 354: case kDCLReceivePacketStartOp : ! 355: DCLReceivePacketStart ( ! 356: &pCurrentDCLCommand, ! 357: packetHeader, ! 358: pPacketBuffer, ! 359: pPacketSize, ! 360: pGetNextPacket); ! 361: break; ! 362: ! 363: case kDCLReceivePacketOp : ! 364: DCLReceivePacket ( ! 365: &pCurrentDCLCommand, ! 366: packetHeader, ! 367: pPacketBuffer, ! 368: pPacketSize, ! 369: pGetNextPacket); ! 370: break; ! 371: ! 372: case kDCLReceiveBufferOp : ! 373: DCLReceiveBuffer ( ! 374: &pCurrentDCLCommand, ! 375: packetHeader, ! 376: pPacketBuffer, ! 377: pPacketSize, ! 378: pGetNextPacket); ! 379: break; ! 380: ! 381: case kDCLCallProcOp : ! 382: pDCLCallProc = (DCLCallProcPtr) pCurrentDCLCommand; ! 383: // Call the handler if there is one. ! 384: if (pDCLCallProc->proc != NULL) ! 385: (*(pDCLCallProc->proc)) ((DCLCommandPtr) pDCLCallProc); ! 386: ! 387: pCurrentDCLCommand = pCurrentDCLCommand->pNextDCLCommand; ! 388: *pGetNextPacket = false; ! 389: break; ! 390: ! 391: case kDCLJumpOp : ! 392: pDCLJump = (DCLJumpPtr) pCurrentDCLCommand; ! 393: pCurrentDCLCommand = (DCLCommandPtr) pDCLJump->pJumpDCLLabel; ! 394: *pGetNextPacket = false; ! 395: break; ! 396: ! 397: default : ! 398: pCurrentDCLCommand = pCurrentDCLCommand->pNextDCLCommand; ! 399: *pGetNextPacket = false; ! 400: break; ! 401: } ! 402: ! 403: // Update current DCL command. ! 404: *ppCurrentDCLCommand = pCurrentDCLCommand; ! 405: } ! 406: ! 407: //////////////////////////////////////////////////////////////////////////////// ! 408: // ! 409: // FWRunTranslatedTalkingDCLEngine ! 410: // ! 411: // This routine runs the current DCL command using the given packet. It will ! 412: // update the current DCL command, packet buffer pointer, packet size, and will ! 413: // set get next packet to true if it needs another packet. ! 414: //zzz maybe a vector table would be nice ! 415: // ! 416: ! 417: static void RunTalkingDCLEngine( ! 418: UInt32 * packetHeader, ! 419: DCLCommandPtr *ppCurrentDCLCommand, ! 420: UInt8 * *pPacketBuffer, ! 421: UInt32 *pPacketSize, ! 422: bool *pGetNextPacket) ! 423: { ! 424: DCLCommandPtr pCurrentDCLCommand; ! 425: DCLCallProcPtr pDCLCallProc; ! 426: DCLJumpPtr pDCLJump; ! 427: DCLSetTagSyncBitsPtr pDCLSetTagSyncBits; ! 428: ! 429: // Run the current DCL command. ! 430: pCurrentDCLCommand = *ppCurrentDCLCommand; ! 431: switch (pCurrentDCLCommand->opcode & ~kFWDCLOpFlagMask) ! 432: { ! 433: case kDCLSendPacketStartOp : ! 434: case kDCLSendPacketOp : ! 435: DCLSendPacket ( ! 436: &pCurrentDCLCommand, ! 437: pPacketBuffer, ! 438: pPacketSize, ! 439: pGetNextPacket); ! 440: break; ! 441: ! 442: case kDCLSendBufferOp : ! 443: DCLSendBuffer ( ! 444: &pCurrentDCLCommand, ! 445: pPacketBuffer, ! 446: pPacketSize, ! 447: pGetNextPacket); ! 448: break; ! 449: ! 450: case kDCLCallProcOp : ! 451: pDCLCallProc = (DCLCallProcPtr) pCurrentDCLCommand; ! 452: // Call the handler if there is one. ! 453: if (pDCLCallProc->proc != NULL) ! 454: (*(pDCLCallProc->proc)) ((DCLCommandPtr) pDCLCallProc); ! 455: pCurrentDCLCommand = pCurrentDCLCommand->pNextDCLCommand; ! 456: *pGetNextPacket = false; ! 457: break; ! 458: ! 459: case kDCLJumpOp : ! 460: pDCLJump = (DCLJumpPtr) pCurrentDCLCommand; ! 461: pCurrentDCLCommand = (DCLCommandPtr) pDCLJump->pJumpDCLLabel; ! 462: *pGetNextPacket = false; ! 463: break; ! 464: ! 465: case kDCLLabelOp : ! 466: pCurrentDCLCommand = pCurrentDCLCommand->pNextDCLCommand; ! 467: *pGetNextPacket = false; ! 468: break; ! 469: ! 470: case kDCLSetTagSyncBitsOp : ! 471: pDCLSetTagSyncBits = (DCLSetTagSyncBitsPtr) pCurrentDCLCommand; ! 472: *packetHeader &= ~(kFWIsochTag | kFWIsochSy); ! 473: *packetHeader |= (pDCLSetTagSyncBits->tagBits << kFWIsochTagPhase); ! 474: *packetHeader |= (pDCLSetTagSyncBits->syncBits << kFWIsochSyPhase); ! 475: pCurrentDCLCommand = pCurrentDCLCommand->pNextDCLCommand; ! 476: *pGetNextPacket = false; ! 477: break; ! 478: ! 479: default : ! 480: pCurrentDCLCommand = pCurrentDCLCommand->pNextDCLCommand; ! 481: *pGetNextPacket = false; ! 482: break; ! 483: } ! 484: ! 485: // Update current DCL command. ! 486: *ppCurrentDCLCommand = pCurrentDCLCommand; ! 487: } ! 488: ! 489: OSDefineMetaClass( IODCLTranslator, IODCLProgram ) ! 490: OSDefineAbstractStructors(IODCLTranslator, IODCLProgram) ! 491: ! 492: bool IODCLTranslator::init(DCLCommandPtr toInterpret) ! 493: { ! 494: if(!IODCLProgram::init()) ! 495: return false; ! 496: ! 497: // Allocate buffers etc. for programs ! 498: ! 499: fToInterpret = toInterpret; ! 500: return true; ! 501: } ! 502: ! 503: IOReturn IODCLTranslator::notify(UInt32 notificationType, ! 504: DCLCommandPtr *dclCommandList, UInt32 numDCLCommands) ! 505: { ! 506: return kIOReturnSuccess; // Nothing to do, we're interpreting anyway ! 507: } ! 508: ! 509: IOReturn IODCLTranslator::allocateHW(IOFWSpeed speed, UInt32 chan) ! 510: { ! 511: if(!fHWProgram) ! 512: return kIOReturnInternalError; ! 513: return fHWProgram->allocateHW(speed, chan); ! 514: } ! 515: IOReturn IODCLTranslator::releaseHW() ! 516: { ! 517: if(!fHWProgram) ! 518: return kIOReturnInternalError; ! 519: return fHWProgram->releaseHW(); ! 520: } ! 521: ! 522: void IODCLTranslator::stop() ! 523: { ! 524: fHWProgram->stop(); ! 525: } ! 526: ! 527: void IODCLTranslator::ListeningDCLPingPongProc(DCLCommandPtr pDCLCommand) ! 528: { ! 529: IODCLTranslator * me; ! 530: DCLCommandPtr pCurrentDCLCommand; ! 531: DCLTransferPacketPtr pDCLTransferPacket; ! 532: UInt8 * packetBuffer; ! 533: UInt32 packetHeader; ! 534: UInt32 packetSize; ! 535: UInt32 packetNum; ! 536: bool getNextPacket; ! 537: ! 538: me = (IODCLTranslator *)((DCLCallProcPtr)pDCLCommand)->procData; ! 539: pCurrentDCLCommand = me->fCurrentDCLCommand; ! 540: pDCLTransferPacket = &me->fTransfers[me->fPingCount * kNumPacketsPerPingPong]; ! 541: // Run all packets through DCL program. ! 542: for (packetNum = 0; ! 543: ((packetNum < kNumPacketsPerPingPong) && (pCurrentDCLCommand != NULL)); ! 544: packetNum++) { ! 545: // Compute packet size. ! 546: packetBuffer = (UInt8 *)pDCLTransferPacket->buffer; ! 547: packetHeader = *((UInt32 *) packetBuffer); ! 548: packetBuffer += sizeof (UInt32); ! 549: packetSize = (packetHeader & kFWIsochDataLength) >> kFWIsochDataLengthPhase; ! 550: ! 551: // Run this packet through DCL program. ! 552: getNextPacket = false; ! 553: while ((!getNextPacket) && (pCurrentDCLCommand != NULL)) { ! 554: RunListeningDCLEngine ( ! 555: &pCurrentDCLCommand, ! 556: packetHeader, ! 557: &packetBuffer, ! 558: &packetSize, ! 559: &getNextPacket); ! 560: } ! 561: ! 562: // Update for next packet. ! 563: pDCLTransferPacket++; ! 564: } ! 565: ! 566: // Update DCL translation data. ! 567: me->fCurrentDCLCommand = pCurrentDCLCommand; ! 568: me->fPingCount++; ! 569: if(me->fPingCount > kNumPingPongs) ! 570: me->fPingCount = 0; ! 571: } ! 572: ! 573: void IODCLTranslator::TalkingDCLPingPongProc(DCLCommandPtr pDCLCommand) ! 574: { ! 575: IODCLTranslator * me; ! 576: DCLCommandPtr pCurrentDCLCommand; ! 577: DCLTransferPacketPtr pDCLTransferPacket; ! 578: UInt8 * packetBuffer; ! 579: UInt32 packetHeader; ! 580: UInt32 packetSize; ! 581: UInt32 packetNum; ! 582: bool getNextPacket; ! 583: ! 584: me = (IODCLTranslator *)((DCLCallProcPtr)pDCLCommand)->procData; ! 585: pCurrentDCLCommand = me->fCurrentDCLCommand; ! 586: pDCLTransferPacket = &me->fTransfers[me->fPingCount * kNumPacketsPerPingPong]; ! 587: // Run all packets through DCL program. ! 588: for (packetNum = 0; ! 589: ((packetNum < kNumPacketsPerPingPong) && (pCurrentDCLCommand != NULL)); ! 590: packetNum++) { ! 591: // Compute packet size. ! 592: packetBuffer = (UInt8 *)pDCLTransferPacket->buffer; ! 593: packetSize = sizeof (UInt32); ! 594: ! 595: // Run this packet through DCL program. ! 596: getNextPacket = false; ! 597: while ((!getNextPacket) && (pCurrentDCLCommand != NULL)) { ! 598: RunTalkingDCLEngine (&(me->fPacketHeader), ! 599: &pCurrentDCLCommand, ! 600: &packetBuffer, ! 601: &packetSize, ! 602: &getNextPacket); ! 603: } ! 604: // Update packet header. ! 605: packetSize -= 4;//zzz not the best way ! 606: packetHeader = ! 607: (packetSize << kFWIsochDataLengthPhase) | ! 608: (me->fPacketHeader & ~(kFWIsochDataLength)); ! 609: *((UInt32 *) packetBuffer) = packetHeader; ! 610: ! 611: // Update send packet DCL. ! 612: packetSize += 4;//zzz really, not the best way ! 613: // Change the transfer packet command. ! 614: pDCLTransferPacket->size = packetSize; ! 615: // Send notification to DCL compiler. ! 616: me->fHWProgram->notify(kFWDCLModifyNotification, ! 617: (DCLCommandPtr *) pDCLTransferPacket, 1); ! 618: ! 619: // Update for next packet. ! 620: pDCLTransferPacket++; ! 621: } ! 622: ! 623: // Update DCL translation data. ! 624: me->fCurrentDCLCommand = pCurrentDCLCommand; ! 625: me->fPingCount++; ! 626: if(me->fPingCount > kNumPingPongs) ! 627: me->fPingCount = 0; ! 628: } ! 629: ! 630: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ! 631: OSDefineMetaClassAndStructors(IODCLTranslateTalk, IODCLTranslator) ! 632: ! 633: IOReturn IODCLTranslateTalk::compile(IOFWSpeed speed, UInt32 chan) ! 634: { ! 635: int pingPongNum; ! 636: int packetNum; ! 637: DCLTransferPacketPtr pDCLTransferPacket = &fTransfers[0]; ! 638: DCLCallProcPtr pDCLPingPongProc = &fCalls[0]; ! 639: UInt8 *pingPongBuffer = fBuffer; ! 640: ! 641: if(!fHWProgram) ! 642: return kIOReturnInternalError; ! 643: ! 644: fPacketHeader = chan << kFWIsochChanNumPhase; ! 645: ! 646: // Create label for start of loop. ! 647: fStartLabel.pNextDCLCommand = (DCLCommandPtr)pDCLTransferPacket; ! 648: fStartLabel.opcode = kDCLLabelOp; ! 649: ! 650: // Create kNumPingPongs ping pong buffer lists of kNumPacketsPerPingPong ! 651: // packets each. ! 652: for (pingPongNum = 0; pingPongNum < kNumPingPongs; pingPongNum++) { ! 653: // Create transfer DCL for each packet. ! 654: for (packetNum = 0; packetNum < kNumPacketsPerPingPong; packetNum++) { ! 655: // Receive one packet up to kMaxIsochPacketSize bytes. ! 656: pDCLTransferPacket->pNextDCLCommand = (DCLCommandPtr)(pDCLTransferPacket+1); ! 657: pDCLTransferPacket->opcode = kDCLSendPacketWithHeaderStartOp | kFWDCLOpDynamicFlag; ! 658: pDCLTransferPacket->buffer = pingPongBuffer; ! 659: pDCLTransferPacket->size = kMaxIsochPacketSize; ! 660: pingPongBuffer += kMaxIsochPacketSize; ! 661: pDCLTransferPacket++; ! 662: } ! 663: // Correct next opcode for last transfer op. ! 664: (pDCLTransferPacket-1)->pNextDCLCommand = (DCLCommandPtr)pDCLPingPongProc; ! 665: // Call the ping pong proc. ! 666: pDCLPingPongProc->pNextDCLCommand = (DCLCommandPtr) pDCLTransferPacket; ! 667: pDCLPingPongProc->opcode = kDCLCallProcOp; ! 668: pDCLPingPongProc->proc = TalkingDCLPingPongProc; ! 669: pDCLPingPongProc->procData = (UInt32) this; ! 670: pDCLPingPongProc++; ! 671: } ! 672: // Correct next opcode for last call op. ! 673: (pDCLPingPongProc-1)->pNextDCLCommand = (DCLCommandPtr)&fJumpToStart; ! 674: ! 675: // Loop to start of ping pong. ! 676: fJumpToStart.pNextDCLCommand = NULL; ! 677: fJumpToStart.opcode = kDCLJumpOp | kFWDCLOpDynamicFlag; ! 678: fJumpToStart.pJumpDCLLabel = &fStartLabel; ! 679: ! 680: return fHWProgram->compile(speed, chan); ! 681: } ! 682: ! 683: IOReturn IODCLTranslateTalk::start() ! 684: { ! 685: int i; ! 686: fPingCount = 0; ! 687: // Prime all buffers ! 688: for(i=0; i<kNumPingPongs; i++) { ! 689: TalkingDCLPingPongProc((DCLCommandPtr)&fCalls[i]); ! 690: } ! 691: return fHWProgram->start(); ! 692: } ! 693: ! 694: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ! 695: OSDefineMetaClassAndStructors(IODCLTranslateListen, IODCLTranslator) ! 696: ! 697: IOReturn IODCLTranslateListen::compile(IOFWSpeed speed, UInt32 chan) ! 698: { ! 699: int pingPongNum; ! 700: int packetNum; ! 701: DCLTransferPacketPtr pDCLTransferPacket = &fTransfers[0]; ! 702: DCLCallProcPtr pDCLPingPongProc = &fCalls[0]; ! 703: UInt8 *pingPongBuffer = fBuffer; ! 704: ! 705: if(!fHWProgram) ! 706: return kIOReturnInternalError; ! 707: ! 708: fPacketHeader = chan << kFWIsochChanNumPhase; ! 709: ! 710: // Create label for start of loop. ! 711: fStartLabel.pNextDCLCommand = (DCLCommandPtr)pDCLTransferPacket; ! 712: fStartLabel.opcode = kDCLLabelOp; ! 713: ! 714: // Create kNumPingPongs ping pong buffer lists of kNumPacketsPerPingPong ! 715: // packets each. ! 716: for (pingPongNum = 0; pingPongNum < kNumPingPongs; pingPongNum++) { ! 717: // Create transfer DCL for each packet. ! 718: for (packetNum = 0; packetNum < kNumPacketsPerPingPong; packetNum++) { ! 719: // Receive one packet up to kMaxIsochPacketSize bytes. ! 720: pDCLTransferPacket->pNextDCLCommand = (DCLCommandPtr)(pDCLTransferPacket+1); ! 721: pDCLTransferPacket->opcode = kDCLReceivePacketStartOp | kFWDCLOpDynamicFlag; ! 722: pDCLTransferPacket->buffer = pingPongBuffer; ! 723: pDCLTransferPacket->size = kMaxIsochPacketSize; ! 724: pingPongBuffer += kMaxIsochPacketSize; ! 725: pDCLTransferPacket++; ! 726: } ! 727: // Correct next opcode for last transfer op. ! 728: (pDCLTransferPacket-1)->pNextDCLCommand = (DCLCommandPtr)pDCLPingPongProc; ! 729: // Call the ping pong proc. ! 730: pDCLPingPongProc->pNextDCLCommand = (DCLCommandPtr) pDCLTransferPacket; ! 731: pDCLPingPongProc->opcode = kDCLCallProcOp; ! 732: pDCLPingPongProc->proc = ListeningDCLPingPongProc; ! 733: pDCLPingPongProc->procData = (UInt32) this; ! 734: pDCLPingPongProc++; ! 735: } ! 736: // Correct next opcode for last call op. ! 737: (pDCLPingPongProc-1)->pNextDCLCommand = (DCLCommandPtr)&fJumpToStart; ! 738: ! 739: // Loop to start of ping pong. ! 740: fJumpToStart.pNextDCLCommand = NULL; ! 741: fJumpToStart.opcode = kDCLJumpOp | kFWDCLOpDynamicFlag; ! 742: fJumpToStart.pJumpDCLLabel = &fStartLabel; ! 743: ! 744: return fHWProgram->compile(speed, chan); ! 745: } ! 746: ! 747: IOReturn IODCLTranslateListen::start() ! 748: { ! 749: fPingCount = 0; ! 750: return fHWProgram->start(); ! 751: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.