Annotation of XNU/iokit/Families/IOFireWire/IOFWDCLTranslator.cpp, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

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