/* * Copyright (c) 1998-2001 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * The contents of this file constitute Original Code as defined in and * are subject to the Apple Public Source License Version 1.1 (the * "License"). You may not use this file except in compliance with the * License. Please obtain a copy of the License at * http://www.apple.com/publicsource and read it before using this file. * * This Original Code and all software distributed under the License are * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the * License for the specific language governing rights and limitations * under the License. * * @APPLE_LICENSE_HEADER_END@ */ /* * IOFWUserClientIsoch.cpp * IOFireWireFamily * * Created by NWG on Mon Mar 12 2001. * Copyright (c) 2001 Apple Computer, Inc. All rights reserved. * */ #include #include #include #include #include #include "IOFireWireUserClient.h" #include "IOFWUserIsochPort.h" #include "IOFWUserIsochChannel.h" void IOFireWireUserClient::initIsochMethodTable() { // // --- isoch methods ---------- // fMethods[kFWIsochPort_Allocate].object = this ; fMethods[kFWIsochPort_Allocate].func = (IOMethod) & IOFireWireUserClient::isochPortAllocate ; fMethods[kFWIsochPort_Allocate].count0 = sizeof(FWIsochPortAllocateParams) ; fMethods[kFWIsochPort_Allocate].count1 = sizeof(FWKernIsochPortRef) ; fMethods[kFWIsochPort_Allocate].flags = kIOUCStructIStructO ; fMethods[kFWIsochPort_Release].object = this ; fMethods[kFWIsochPort_Release].func = (IOMethod) & IOFireWireUserClient::isochPortRelease ; fMethods[kFWIsochPort_Release].count0 = 1 ; fMethods[kFWIsochPort_Release].count1 = 0 ; fMethods[kFWIsochPort_Release].flags = kIOUCScalarIScalarO ; fMethods[kFWIsochPort_GetSupported].object = this ; fMethods[kFWIsochPort_GetSupported].func = (IOMethod) & IOFireWireUserClient::isochPortGetSupported ; fMethods[kFWIsochPort_GetSupported].count0 = 1 ; fMethods[kFWIsochPort_GetSupported].count1 = 3 ; fMethods[kFWIsochPort_GetSupported].flags = kIOUCScalarIScalarO ; fMethods[kFWIsochPort_AllocatePort].object = this ; fMethods[kFWIsochPort_AllocatePort].func = (IOMethod) & IOFireWireUserClient::isochPortAllocatePort ; fMethods[kFWIsochPort_AllocatePort].count0 = 3 ; fMethods[kFWIsochPort_AllocatePort].count1 = 0 ; fMethods[kFWIsochPort_AllocatePort].flags = kIOUCScalarIScalarO ; fMethods[kFWIsochPort_ReleasePort].object = this ; fMethods[kFWIsochPort_ReleasePort].func = (IOMethod) & IOFireWireUserClient::isochPortReleasePort ; fMethods[kFWIsochPort_ReleasePort].count0 = 1 ; fMethods[kFWIsochPort_ReleasePort].count1 = 0 ; fMethods[kFWIsochPort_ReleasePort].flags = kIOUCScalarIScalarO ; fMethods[kFWIsochPort_Start].object = this ; fMethods[kFWIsochPort_Start].func = (IOMethod) & IOFireWireUserClient::isochPortStart ; fMethods[kFWIsochPort_Start].count0 = 1 ; fMethods[kFWIsochPort_Start].count1 = 0 ; fMethods[kFWIsochPort_Start].flags = kIOUCScalarIScalarO ; fMethods[kFWIsochPort_Stop].object = this ; fMethods[kFWIsochPort_Stop].func = (IOMethod) & IOFireWireUserClient::isochPortStop ; fMethods[kFWIsochPort_Stop].count0 = 1 ; fMethods[kFWIsochPort_Stop].count1 = 0 ; fMethods[kFWIsochPort_Stop].flags = kIOUCScalarIScalarO ; // --- local isoch port methods ---------------------- fMethods[kFWLocalIsochPort_Allocate].object = this ; fMethods[kFWLocalIsochPort_Allocate].func = (IOMethod) & IOFireWireUserClient::localIsochPortAllocate ; fMethods[kFWLocalIsochPort_Allocate].count0 = sizeof(FWLocalIsochPortAllocateParams) ; fMethods[kFWLocalIsochPort_Allocate].count1 = sizeof(FWKernIsochPortRef) ; fMethods[kFWLocalIsochPort_Allocate].flags = kIOUCStructIStructO ; fMethods[kFWLocalIsochPort_ModifyJumpDCL].object = this ; fMethods[kFWLocalIsochPort_ModifyJumpDCL].func = (IOMethod) & IOFireWireUserClient::localIsochPortModifyJumpDCL ; fMethods[kFWLocalIsochPort_ModifyJumpDCL].count0 = 3 ; fMethods[kFWLocalIsochPort_ModifyJumpDCL].count1 = 0 ; fMethods[kFWLocalIsochPort_ModifyJumpDCL].flags = kIOUCScalarIScalarO ; fMethods[kFWLocalIsochPort_ModifyTransferPacketDCLSize].object = this ; fMethods[kFWLocalIsochPort_ModifyTransferPacketDCLSize].func = (IOMethod) & IOFireWireUserClient::localIsochPortModifyJumpDCLSize ; fMethods[kFWLocalIsochPort_ModifyTransferPacketDCLSize].count0 = 3 ; fMethods[kFWLocalIsochPort_ModifyTransferPacketDCLSize].count1 = 0 ; fMethods[kFWLocalIsochPort_ModifyTransferPacketDCLSize].flags = kIOUCScalarIScalarO ; // --- isoch channel methods ------------------------- fMethods[kFWIsochChannel_Allocate].object = this ; fMethods[kFWIsochChannel_Allocate].func = (IOMethod) & IOFireWireUserClient::isochChannelAllocate ; fMethods[kFWIsochChannel_Allocate].count0 = 3 ; fMethods[kFWIsochChannel_Allocate].count1 = 1 ; fMethods[kFWIsochChannel_Allocate].flags = kIOUCScalarIScalarO ; fMethods[kFWIsochChannel_Release].object = this ; fMethods[kFWIsochChannel_Release].func = (IOMethod) & IOFireWireUserClient::isochChannelRelease ; fMethods[kFWIsochChannel_Release].count0 = 1 ; fMethods[kFWIsochChannel_Release].count1 = 0 ; fMethods[kFWIsochChannel_Release].flags = kIOUCScalarIScalarO ; fMethods[kFWIsochChannel_UserAllocateChannelBegin].object = this ; fMethods[kFWIsochChannel_UserAllocateChannelBegin].func = (IOMethod) & IOFireWireUserClient::isochChannelUserAllocateChannelBegin ; fMethods[kFWIsochChannel_UserAllocateChannelBegin].count0 = 4 ; fMethods[kFWIsochChannel_UserAllocateChannelBegin].count1 = 2 ; fMethods[kFWIsochChannel_UserAllocateChannelBegin].flags = kIOUCScalarIScalarO ; fMethods[kFWIsochChannel_UserReleaseChannelComplete].object = this ; fMethods[kFWIsochChannel_UserReleaseChannelComplete].func = (IOMethod) & IOFireWireUserClient::isochChannelUserReleaseChannelComplete ; fMethods[kFWIsochChannel_UserReleaseChannelComplete].count0 = 1 ; fMethods[kFWIsochChannel_UserReleaseChannelComplete].count1 = 0 ; fMethods[kFWIsochChannel_UserReleaseChannelComplete].flags = kIOUCScalarIScalarO ; } void IOFireWireUserClient::initIsochAsyncMethodTable() { fAsyncMethods[kFWSetAsyncRef_IsochChannelForceStop].object = this ; fAsyncMethods[kFWSetAsyncRef_IsochChannelForceStop].func = (IOAsyncMethod) & IOFireWireUserClient::setAsyncRef_IsochChannelForceStop ; fAsyncMethods[kFWSetAsyncRef_IsochChannelForceStop].count0 = 3 ; fAsyncMethods[kFWSetAsyncRef_IsochChannelForceStop].count1 = 0 ; fAsyncMethods[kFWSetAsyncRef_IsochChannelForceStop].flags = kIOUCScalarIScalarO ; fAsyncMethods[kFWSetAsyncRef_DCLCallProc].object = this ; fAsyncMethods[kFWSetAsyncRef_DCLCallProc].func = (IOAsyncMethod) & IOFireWireUserClient::setAsyncRef_DCLCallProc ; fAsyncMethods[kFWSetAsyncRef_DCLCallProc].count0 = 2 ; fAsyncMethods[kFWSetAsyncRef_DCLCallProc].count1 = 0 ; fAsyncMethods[kFWSetAsyncRef_DCLCallProc].flags = kIOUCScalarIScalarO ; } // // isoch port // IOReturn IOFireWireUserClient::isochPortAllocate( FWIsochPortAllocateParams* inParams, FWKernIsochPortRef* outPortRef) { IOFWUserIsochPortProxy* newPort = new IOFWUserIsochPortProxy() ; if (!newPort) { IOLog("%s %u: newPort==nil!\n", __FILE__, __LINE__) ; return kIOReturnNoMemory ; } if (!newPort->init(this)) { IOLog("IOFireWireUserClient::isochPortAllocate: port init failed\n") ; newPort->release() ; return kIOReturnInternalError ; } IOReturn result = addObjectToSet( newPort, fUserIsochPorts ) ; // pass new port out to user *outPortRef = newPort ; return result ; } IOReturn IOFireWireUserClient::isochPortRelease( FWKernIsochPortRef inPortRef) { if (!OSDynamicCast(IOFWUserIsochPortProxy, inPortRef)) return kIOReturnBadArgument ; removeObjectFromSet( inPortRef, fUserIsochPorts ) ; return kIOReturnSuccess ; } IOReturn IOFireWireUserClient::isochPortGetSupported( FWKernIsochPortRef inPortRef, IOFWSpeed* outMaxSpeed, UInt32* outChanSupportedHi, UInt32* outChanSupportedLo) { if (!OSDynamicCast(IOFWUserIsochPortProxy, inPortRef)) return kIOReturnBadArgument ; UInt64 chanSupported ; IOReturn result = kIOReturnSuccess ; result = inPortRef->getSupported(*outMaxSpeed, chanSupported) ; *outChanSupportedHi = (UInt32)(chanSupported >> 32) ; *outChanSupportedLo = (UInt32)(chanSupported & 0xFFFFFFFF) ; return result ; } IOReturn IOFireWireUserClient::isochPortAllocatePort( FWKernIsochPortRef inPortRef, IOFWSpeed inSpeed, UInt32 inChannel) { if (!OSDynamicCast(IOFWUserIsochPortProxy, inPortRef)) return kIOReturnBadArgument ; return inPortRef->allocatePort(inSpeed, inChannel) ; } IOReturn IOFireWireUserClient::isochPortReleasePort( FWKernIsochPortRef inPortRef) { if (!OSDynamicCast(IOFWUserIsochPortProxy, inPortRef)) return kIOReturnBadArgument ; return inPortRef->releasePort() ; } IOReturn IOFireWireUserClient::isochPortStart( FWKernIsochPortRef inPortRef) { if (!OSDynamicCast(IOFWUserIsochPortProxy, inPortRef)) return kIOReturnBadArgument ; return inPortRef->start() ; } IOReturn IOFireWireUserClient::isochPortStop( FWKernIsochPortRef inPortRef) { if (!OSDynamicCast(IOFWUserIsochPortProxy, inPortRef)) return kIOReturnBadArgument ; return inPortRef->stop() ; } IOReturn IOFireWireUserClient::localIsochPortAllocate( FWLocalIsochPortAllocateParams* inParams, FWKernIsochPortRef* outPortRef) { IOReturn result = kIOReturnSuccess ; IOFWUserLocalIsochPortProxy* newPort = new IOFWUserLocalIsochPortProxy ; if (!newPort) { IOLog("%s %u: newPort == nil!\n", __FILE__, __LINE__) ; return kIOReturnNoMemory ; } if (!newPort->initWithUserDCLProgram(inParams, this)) { IOLog("%s %u: newPort->initWithUserDCLProgram failed!\n", __FILE__, __LINE__) ; newPort->release() ; result = kIOReturnError ; } else { result = addObjectToSet( newPort, fUserIsochPorts ) ; // pass new port out to user *outPortRef = newPort ; } return result ; } IOReturn IOFireWireUserClient::localIsochPortModifyJumpDCL( FWKernIsochPortRef inPortRef, UInt32 inJumpDCLCompilerData, UInt32 inLabelDCLCompilerData) { IOFWUserLocalIsochPortProxy* portProxy ; if (NULL == (portProxy = OSDynamicCast(IOFWUserLocalIsochPortProxy, inPortRef)) ) return kIOReturnBadArgument ; return portProxy->modifyJumpDCL(inJumpDCLCompilerData, inLabelDCLCompilerData) ; } IOReturn IOFireWireUserClient::localIsochPortModifyJumpDCLSize( FWKernIsochPortRef inPortRef, UInt32 dclCompilerData, IOByteCount newSize ) { IOFWUserLocalIsochPortProxy* portProxy ; if (NULL == (portProxy = OSDynamicCast( IOFWUserLocalIsochPortProxy, inPortRef)) ) return kIOReturnBadArgument ; return portProxy->modifyJumpDCLSize( dclCompilerData, newSize ) ; } IOReturn IOFireWireUserClient::setAsyncRef_DCLCallProc( OSAsyncReference asyncRef, FWKernIsochPortRef inPortRef, DCLCallCommandProcPtr inProc ) { IOFWUserLocalIsochPortProxy* port = OSDynamicCast(IOFWUserLocalIsochPortProxy, inPortRef) ; if (!port) return kIOReturnBadArgument ; return port->setAsyncRef_DCLCallProc(asyncRef, inProc ) ; } // // --- isoch channel ---------- // IOReturn IOFireWireUserClient::isochChannelForceStopHandler( void* refCon, IOFWIsochChannel* isochChannelID, UInt32 stopCondition) { return kIOReturnSuccess ; } IOReturn IOFireWireUserClient::isochChannelAllocate( bool inDoIRM, UInt32 inPacketSize, IOFWSpeed inPrefSpeed, FWKernIsochChannelRef* outIsochChannelRef) { IOReturn result = kIOReturnSuccess ; // this code the same as IOFireWireController::createIsochChannel // must update this code when controller changes. We do this because // we are making IOFWUserIsochChannel objects, not IOFWIsochChannel // objects IOFWUserIsochChannel* newChannel = new IOFWUserIsochChannel ; if (!newChannel) { IOLog("%s %u: couldn't make newChannel == nil!\n", __FILE__, __LINE__) ; result = kIOReturnNoMemory ; } if (kIOReturnSuccess == result) if (!newChannel->init(fOwner->getController(), inDoIRM, inPacketSize, inPrefSpeed, & IOFireWireUserClient::isochChannelForceStopHandler, this)) { newChannel->release() ; newChannel = NULL ; result = kIOReturnError ; } if (kIOReturnSuccess == result) { result = addObjectToSet( newChannel, fUserIsochChannels ) ; } *outIsochChannelRef = newChannel ; return result ; } IOReturn IOFireWireUserClient::isochChannelRelease( FWKernIsochChannelRef inChannelRef) { if (!OSDynamicCast(IOFWUserIsochChannel, inChannelRef)) return kIOReturnBadArgument ; // IOLockLock(fSetLock) ; // fUserIsochChannels->removeObject(inChannelRef) ; // IOLockUnlock(fSetLock) ; removeObjectFromSet( inChannelRef, fUserIsochChannels ) ; return kIOReturnSuccess ; } IOReturn IOFireWireUserClient::isochChannelUserAllocateChannelBegin( FWKernIsochChannelRef inChannelRef, IOFWSpeed inSpeed, UInt32 inAllowedChansHi, UInt32 inAllowedChansLo, IOFWSpeed* outSpeed, UInt32* outChannel) { if (!OSDynamicCast(IOFWUserIsochChannel, inChannelRef)) return kIOReturnBadArgument ; return inChannelRef->userAllocateChannelBegin(inSpeed, inAllowedChansHi, inAllowedChansLo, outSpeed, outChannel) ; } IOReturn IOFireWireUserClient::isochChannelUserReleaseChannelComplete( FWKernIsochChannelRef inChannelRef) { if (!OSDynamicCast(IOFWUserIsochChannel, inChannelRef)) return kIOReturnBadArgument ; return inChannelRef->userReleaseChannelComplete() ; } IOReturn IOFireWireUserClient::setAsyncRef_IsochChannelForceStop( OSAsyncReference asyncRef, void* inCallback, void* inUserRefCon, void*, void*, void*, void*) { return kIOReturnUnsupported ; }