/* * IOFWLocalIsochPort.cpp * IOFireWireFamily * * Created by Niels on Tue Mar 25 2003. * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. * * $ Log:IOFWLocalIsochPort.cpp,v $ */ #import "IOFWLocalIsochPort.h" #import "IOFWDCLProgram.h" #import "IOFireWireController.h" #import "FWDebugging.h" OSDefineMetaClassAndStructors(IOFWLocalIsochPort, IOFWIsochPort) OSMetaClassDefineReservedUnused(IOFWLocalIsochPort, 0); OSMetaClassDefineReservedUnused(IOFWLocalIsochPort, 1); bool IOFWLocalIsochPort :: init ( IODCLProgram * program, IOFireWireController * control) { if ( ! IOFWIsochPort::init( ) ) return false; fProgram = program; // belongs to us. fControl = control; return true; } void IOFWLocalIsochPort::free() { if ( fProgram ) { fProgram->stop() ; fProgram->release () ; fProgram = NULL ; } IOFWIsochPort::free(); } // Return maximum speed and channels supported // (bit n set = chan n supported) IOReturn IOFWLocalIsochPort::getSupported(IOFWSpeed &maxSpeed, UInt64 &chanSupported) { maxSpeed = kFWSpeedMaximum; chanSupported = ~(UInt64)0; return kIOReturnSuccess; } /* * Allocate hardware resources for port, via workloop * Then compile program, not on workloop. */ IOReturn IOFWLocalIsochPort::allocatePort(IOFWSpeed speed, UInt32 chan) { IOReturn res; fControl->closeGate(); res = fProgram->allocateHW(speed, chan); fControl->openGate(); if(kIOReturnSuccess != res) return res; return fProgram->compile(speed, chan); // Not on workloop } IOReturn IOFWLocalIsochPort::releasePort() { IOReturn res; fControl->closeGate(); res = fProgram->releaseHW(); fControl->openGate(); return res; } IOReturn IOFWLocalIsochPort::start() { IOReturn res; fControl->closeGate(); res = fProgram->start(); fControl->openGate(); return res; } IOReturn IOFWLocalIsochPort::stop() { fControl->closeGate(); fProgram->stop(); fControl->openGate(); return kIOReturnSuccess; } IOReturn IOFWLocalIsochPort::notify( IOFWDCLNotificationType notificationType, DCLCommand** dclCommandList, UInt32 numDCLCommands) { IOReturn res; res = fProgram->notify(notificationType, dclCommandList, numDCLCommands); return res; } void IOFWLocalIsochPort :: printDCLProgram ( const DCLCommand * dcl, UInt32 count, void (*printFN)( const char *format, ...), unsigned lineDelayMS ) { const DCLCommand * currentDCL = dcl ; UInt32 index = 0 ; #if FIRELOG if( printFN == NULL ) { printFN = FireLog; } #endif if( printFN == NULL ) { // nothing to print if there's no printer function return; } (*printFN)("printDCLProgram program %p, count %x\n", currentDCL, count) ; while ( ( count == 0 || index < count ) && currentDCL ) { (*printFN)("#%x @%p next=%p, cmplrData=%x, op=%u ", index, (UInt32)currentDCL, (UInt32)currentDCL->pNextDCLCommand, (UInt32)currentDCL->compilerData, (int) currentDCL->opcode) ; switch(currentDCL->opcode & ~kFWDCLOpFlagMask) { case kDCLSendPacketStartOp: case kDCLSendPacketWithHeaderStartOp: case kDCLSendPacketOp: case kDCLReceivePacketStartOp: case kDCLReceivePacketOp: (*printFN)("(DCLTransferPacket) buffer=%p, size=%u", (UInt32)((DCLTransferPacket*)currentDCL)->buffer, (int)((DCLTransferPacket*)currentDCL)->size) ; break ; case kDCLSendBufferOp: case kDCLReceiveBufferOp: (*printFN)("(DCLTransferBuffer) buffer=%p, size=%lu, packetSize=%08X, bufferOffset=%08lX", (UInt32)((DCLTransferBuffer*)currentDCL)->buffer, ((DCLTransferBuffer*)currentDCL)->size, ((DCLTransferBuffer*)currentDCL)->packetSize, (UInt32)((DCLTransferBuffer*)currentDCL)->bufferOffset) ; break ; case kDCLCallProcOp: (*printFN)("(DCLCallProc) proc=%p, procData=%08lX", (UInt32)((DCLCallProc*)currentDCL)->proc, (UInt32)((DCLCallProc*)currentDCL)->procData ) ; break ; case kDCLLabelOp: (*printFN)("(DCLLabel)") ; break ; case kDCLJumpOp: (*printFN)("(DCLJump) pJumpDCLLabel=%p", (UInt32)((DCLJump*)currentDCL)->pJumpDCLLabel) ; break ; case kDCLSetTagSyncBitsOp: (*printFN)("(DCLSetTagSyncBits) tagBits=%04lX, syncBits=%04lX", (UInt32)((DCLSetTagSyncBits*)currentDCL)->tagBits, (UInt32)((DCLSetTagSyncBits*)currentDCL)->syncBits) ; break ; case kDCLUpdateDCLListOp: (*printFN)("(DCLUpdateDCLList) dclCommandList=%p, numDCLCommands=%lud\n", (UInt32)((DCLUpdateDCLList*)currentDCL)->dclCommandList, ((DCLUpdateDCLList*)currentDCL)->numDCLCommands) ; for(UInt32 listIndex=0; listIndex < ((DCLUpdateDCLList*)currentDCL)->numDCLCommands; ++listIndex) { (*printFN)("%p ", (UInt32)(((DCLUpdateDCLList*)currentDCL)->dclCommandList)[listIndex]) ; if ( listIndex % 10 == 0 ) (*printFN)("\n") ; IOSleep(8) ; } (*printFN)("\n") ; break ; case kDCLPtrTimeStampOp: (*printFN)("(DCLPtrTimeStamp) timeStampPtr=%p", (UInt32)((DCLPtrTimeStamp*)currentDCL)->timeStampPtr) ; break ; case kDCLSkipCycleOp: (*printFN)("(DCLSkipCycleOp)") ; break ; case kDCLNuDCLLeaderOp: (*printFN)("(DCLNuDCLLeaderOp) DCL pool=%p", ((DCLNuDCLLeader*)currentDCL)->program ) ; break ; } (*printFN)("\n") ; currentDCL = currentDCL->pNextDCLCommand ; ++index ; if ( lineDelayMS ) { IOSleep( lineDelayMS ) ; } } if ( count > 0 ) { if ( index != count ) (*printFN)("unexpected end of program\n") ; if ( currentDCL != NULL ) (*printFN)("program too long for count\n") ; } } IOReturn IOFWLocalIsochPort :: setIsochResourceFlags ( IOFWIsochResourceFlags flags ) { fProgram->setIsochResourceFlags( flags ) ; return kIOReturnSuccess ; } IODCLProgram * IOFWLocalIsochPort::getProgramRef() const { fProgram->retain() ; return fProgram ; }