IOFireWireUserClient.cpp [plain text]
#import "IOFireWireFamilyCommon.h"
#import "IOFireWireNub.h"
#import "IOLocalConfigDirectory.h"
#import "IOFireWireController.h"
#import "IOFireWireDevice.h"
#import "IOFWDCLProgram.h"
#import <sys/proc.h>
#import <IOKit/IOMessage.h>
#include <IOKit/IOKitKeysPrivate.h>
#if FIRELOG
#import <IOKit/firewire/FireLog.h>
#endif
#import <IOKit/firewire/IOFireWireLink.h>
#import "IOFireWireUserClient.h"
#import "IOFWUserPseudoAddressSpace.h"
#import "IOFWUserPhysicalAddressSpace.h"
#import "IOFWUserIsochChannel.h"
#import "IOFWUserIsochPort.h"
#import "IOFireWireLibPriv.h"
#import "IOFireWireLocalNode.h"
#import "IOFWUserCommand.h"
#import "IOFWUserObjectExporter.h"
#import "IOLocalConfigDirectory.h"
#import "IOFWUserAsyncStreamListener.h"
#import "IOFWUserVectorCommand.h"
#import "IOFWUserPHYPacketListener.h"
#if IOFIREWIREUSERCLIENTDEBUG > 0
#undef super
#define super OSObject
OSDefineMetaClassAndStructors( IOFWUserDebugInfo, OSObject )
bool
IOFWUserDebugInfo::init( IOFireWireUserClient & userClient )
{
if ( ! super::init() )
return false ;
fUserClient = & userClient ;
return true ;
}
bool
IOFWUserDebugInfo::serialize (
OSSerialize * s ) const
{
s->clearText() ;
const unsigned objectCount = 1 ;
const OSObject * objects[ objectCount ] =
{
fUserClient->fExporter
} ;
const OSSymbol * keys[ objectCount ] =
{
OSSymbol::withCStringNoCopy("user objects")
} ;
OSDictionary * dict = OSDictionary::withObjects( objects, keys, objectCount ) ;
if ( !dict )
return false ;
bool result = dict->serialize( s ) ;
dict->release() ;
return result ;
}
void
IOFWUserDebugInfo::free ()
{
OSObject::free() ;
}
#endif
#pragma mark -
#undef super
#define super IOUserClient
OSDefineMetaClassAndStructors(IOFireWireUserClient, super ) ;
bool IOFireWireUserClient::initWithTask(
task_t owningTask, void * securityToken, UInt32 type,
OSDictionary * properties)
{
if( properties )
properties->setObject( "IOUserClientCrossEndianCompatible" , kOSBooleanTrue);
bool res = IOUserClient::initWithTask( owningTask, securityToken, type, properties );
fTask = owningTask;
return res;
}
bool
IOFireWireUserClient::start( IOService * provider )
{
if (!OSDynamicCast(IOFireWireNub, provider))
return false ;
if ( ! super::start ( provider ) )
return false;
fOwner = (IOFireWireNub *)provider;
fOwner->retain();
FWTrace( kFWTUserClient, kTPUserClientStart, (uintptr_t)(fOwner->getController()->getLink()), 0, 0, 0 );
fObjectTable[0] = NULL ;
fObjectTable[1] = this ;
fObjectTable[2] = getOwner()->getBus() ;
fBusResetAsyncNotificationRef[0] = 0 ;
fBusResetDoneAsyncNotificationRef[0] = 0 ;
bool result = true ;
fExporter = IOFWUserObjectExporter::createWithOwner( this );
if ( ! fExporter )
result = false ;
#if IOFIREWIREUSERCLIENTDEBUG > 0
if (result)
{
fDebugInfo = OSTypeAlloc( IOFWUserDebugInfo );
if ( fDebugInfo && ! fDebugInfo->init( *this ) )
{
fDebugInfo->release() ;
fDebugInfo = NULL ;
ErrorLog( "Couldn't create statistics object\n" ) ;
}
if ( fDebugInfo )
setProperty( "Debug Info", fDebugInfo ) ;
}
#endif
#if 0
if ( result )
{
proc * p = (proc *)get_bsdtask_info( fTask );
OSNumber* pidProp = OSNumber::withNumber( p->p_pid, sizeof(p->p_pid) * 8 ) ;
if ( pidProp )
{
setProperty( "Owning PID", pidProp ) ;
pidProp->release() ; }
else
result = false ;
}
#endif
return result ;
}
void
IOFireWireUserClient::free()
{
if ( fOwner ) {
FWTrace( kFWTUserClient, kTPUserClientFree, (uintptr_t)(fOwner->getController()->getLink()), (uintptr_t)this, 0, 0 );
} else {
FWTrace( kFWTUserClient, kTPUserClientFree, 0xdeadbeef, (uintptr_t)this, 0, 0 );
}
DebugLog( "free user client %p\n", this ) ;
#if IOFIREWIREUSERCLIENTDEBUG > 0
if ( fDebugInfo )
fDebugInfo->release() ;
#endif
if ( fExporter )
{
fExporter->release() ;
fExporter = NULL ;
}
if ( fOwner )
{
fOwner->release() ;
}
super::free () ;
}
IOReturn
IOFireWireUserClient::clientClose ()
{
FWTrace( kFWTUserClient, kTPUserClientClientClose, (uintptr_t)(fOwner->getController()->getLink()), 0, 0, 0 );
clipMaxRec2K( false );
IOReturn result = userClose() ;
if ( getProvider() && fOwner->isOpen() )
{
DebugLog("IOFireWireUserClient::clientClose(): client left user client open, should call close. Closing...\n") ;
}
else if ( result == kIOReturnNotOpen )
{
result = kIOReturnSuccess ;
}
if ( !terminate() )
{
IOLog("IOFireWireUserClient::clientClose: terminate failed!, getOwner()->isOpen( this ) returned %u\n", getOwner()->isOpen(this)) ;
}
return kIOReturnSuccess;
}
IOReturn
IOFireWireUserClient::clientDied ()
{
if ( fOwner ) {
FWTrace( kFWTUserClient, kTPUserClientClientDied, (uintptr_t)(fOwner->getController()->getLink()), 1, 0, 0 );
} else {
FWTrace( kFWTUserClient, kTPUserClientClientDied, 0xdeadbeef, 1, 0, 0 );
}
if ( fOwner )
{
FWTrace( kFWTUserClient, kTPUserClientClientDied, (uintptr_t)(fOwner->getController()->getLink()), 2, 0, 0 );
fOwner->getBus()->resetBus() ;
}
IOReturn error = clientClose () ;
return error ;
}
IOReturn
IOFireWireUserClient::setProperties (
OSObject * properties )
{
IOReturn result = kIOReturnSuccess ;
OSDictionary* dict = OSDynamicCast( OSDictionary, properties ) ;
if ( dict )
{
OSObject* value = dict->getObject( "unsafe bus resets" ) ;
if ( value and OSDynamicCast(OSNumber, value ) )
{
fUnsafeResets = ( ((OSNumber*)value)->unsigned8BitValue() != 0 ) ;
}
else
{
result = super::setProperties ( properties ) ;
}
}
else
result = super::setProperties ( properties ) ;
return result ;
}
#pragma mark -
static UInt32 getSelectorObjectLookupIndex(UInt32 selector)
{
UInt32 selectorObjectLookupIndex = 1;
switch (selector)
{
case kCycleTime:
case kGetBusCycleTime:
selectorObjectLookupIndex = 2; break;
case kPhysicalAddrSpace_GetSegmentCount_d: case kIsochPort_AllocatePort_d: case kIsochPort_ReleasePort_d: case kIsochPort_Start_d: case kIsochPort_Stop_d: case kLocalIsochPort_ModifyJumpDCL_d: case kLocalIsochPort_Notify_d: case kIsochChannel_UserReleaseChannelComplete_d: case kCommand_Cancel_d: case kIsochPort_SetIsochResourceFlags_d: case kVectorCommandSubmit: case kVectorCommandSetBuffers: case kPHYPacketListenerSetPacketCallback: case kPHYPacketListenerSetSkippedCallback: case kPHYPacketListenerActivate: case kPHYPacketListenerDeactivate: case kPHYPacketListenerClientCommandIsComplete: selectorObjectLookupIndex = 0; break;
default:
break;
};
return selectorObjectLookupIndex;
}
IOReturn
IOFireWireUserClient::externalMethod( uint32_t selector,
IOExternalMethodArguments * arguments,
IOExternalMethodDispatch * dispatch,
OSObject * target,
void * reference)
{
IOReturn result = kIOReturnBadArgument;
IOService *targetObject;
UInt32 actualSelector = selector & 0xFFFF ;
if ( actualSelector >= kNumMethods )
return result;
targetObject = fObjectTable[ getSelectorObjectLookupIndex(actualSelector)] ;
if ( !targetObject )
{
const OSObject * userObject = fExporter->lookupObject( (UserObjectHandle)( selector >> 16 ) ) ;
targetObject = (IOService*)userObject ;
if (targetObject)
{
(targetObject)->release() ; }
else
return result;
}
switch (actualSelector)
{
case kOpen:
result = ((IOFireWireUserClient*) targetObject)->userOpen();
break;
case kOpenWithSessionRef:
result = ((IOFireWireUserClient*) targetObject)->userOpenWithSessionRef((IOFireWireLib::UserObjectHandle) arguments->scalarInput[0]);
break;
case kClose:
result = ((IOFireWireUserClient*) targetObject)->userClose();
break;
case kReadQuad:
result = ((IOFireWireUserClient*) targetObject)->
readQuad((const ReadQuadParams*) arguments->structureInput,
(UInt32*) arguments->structureOutput);
break;
case kRead:
result = ((IOFireWireUserClient*) targetObject)->
read((const ReadParams*) arguments->structureInput,
(IOByteCount*) arguments->structureOutput);
break;
case kWriteQuad:
result = ((IOFireWireUserClient*) targetObject)->writeQuad((const WriteQuadParams*) arguments->structureInput);
break;
case kWrite:
result = ((IOFireWireUserClient*) targetObject)->
write((const WriteParams*) arguments->structureInput,
(IOByteCount*) arguments->structureOutput);
break;
case kCompareSwap:
result = ((IOFireWireUserClient*) targetObject)->
compareSwap((const CompareSwapParams*) arguments->structureInput,
(UInt32*) arguments->structureOutput);
break;
case kBusReset:
result = ((IOFireWireUserClient*) targetObject)->busReset();
break;
case kCycleTime:
{
UInt32 cycleTime;
UInt64 upTime;
result = ((IOFireWireController*) targetObject)->getCycleTimeAndUpTime(cycleTime, upTime);
arguments->scalarOutput[0] = cycleTime;
arguments->scalarOutput[1] = upTime;
}
break;
case kGetGenerationAndNodeID:
{
UInt32 outGeneration;
UInt32 outNodeID;
result = ((IOFireWireUserClient*) targetObject)->getGenerationAndNodeID(&outGeneration,&outNodeID);
arguments->scalarOutput[0] = outGeneration;
arguments->scalarOutput[1] = outNodeID;
}
break;
case kGetLocalNodeID:
{
UInt32 outLocalNodeID;
result = ((IOFireWireUserClient*) targetObject)->getLocalNodeID(&outLocalNodeID);
arguments->scalarOutput[0] = outLocalNodeID;
}
break;
case kGetResetTime:
result = ((IOFireWireUserClient*) targetObject)->getResetTime((AbsoluteTime*) arguments->structureOutput);
break;
case kReleaseUserObject:
result = ((IOFireWireUserClient*) targetObject)->releaseUserObject((UserObjectHandle)arguments->scalarInput[0]);
break;
case kGetOSStringData:
{
UInt32 outTextLength;
result = ((IOFireWireUserClient*) targetObject)->getOSStringData((UserObjectHandle)arguments->scalarInput[0],
(UInt32)arguments->scalarInput[1],
(mach_vm_address_t)arguments->scalarInput[2],
&outTextLength);
arguments->scalarOutput[0] = outTextLength;
}
break;
case kGetOSDataData:
{
IOByteCount outDataLen;
result = ((IOFireWireUserClient*) targetObject)->getOSDataData((UserObjectHandle)arguments->scalarInput[0],
(IOByteCount)arguments->scalarInput[1],
(mach_vm_address_t)arguments->scalarInput[2],
&outDataLen);
arguments->scalarOutput[0] = outDataLen;
}
break;
case kLocalConfigDirectory_Create:
{
UserObjectHandle outDir;
result = ((IOFireWireUserClient*) targetObject)->localConfigDirectory_Create(&outDir);
arguments->scalarOutput[0] = (uint64_t) outDir;
}
break;
case kLocalConfigDirectory_AddEntry_Buffer:
result = ((IOFireWireUserClient*) targetObject)->
localConfigDirectory_addEntry_Buffer((UserObjectHandle)arguments->scalarInput[0],
(int)arguments->scalarInput[1],
(char *)arguments->scalarInput[2],
(UInt32)arguments->scalarInput[3],
(const char *)arguments->scalarInput[4],
(UInt32)arguments->scalarInput[5]);
break;
case kLocalConfigDirectory_AddEntry_UInt32:
result = ((IOFireWireUserClient*) targetObject)->
localConfigDirectory_addEntry_UInt32((UserObjectHandle)arguments->scalarInput[0],
(int)arguments->scalarInput[1],
(UInt32)arguments->scalarInput[2],
(const char *)arguments->scalarInput[3],
(UInt32)arguments->scalarInput[4]);
break;
case kLocalConfigDirectory_AddEntry_FWAddr:
result = ((IOFireWireUserClient*) targetObject)->
localConfigDirectory_addEntry_FWAddr((UserObjectHandle)arguments->scalarInput[0],
(int)arguments->scalarInput[1],
(const char *)arguments->scalarInput[2],
(UInt32)arguments->scalarInput[3],
(FWAddress *) arguments->structureInput);
break;
case kLocalConfigDirectory_AddEntry_UnitDir:
break;
case kLocalConfigDirectory_Publish:
result = ((IOFireWireUserClient*) targetObject)->localConfigDirectory_Publish((UserObjectHandle)arguments->scalarInput[0]);
break;
case kLocalConfigDirectory_Unpublish:
result = ((IOFireWireUserClient*) targetObject)->localConfigDirectory_Unpublish((UserObjectHandle)arguments->scalarInput[0]);
break;
case kPseudoAddrSpace_Allocate:
result = ((IOFireWireUserClient*) targetObject)->
addressSpace_Create((AddressSpaceCreateParams *) arguments->structureInput,
(UserObjectHandle *) arguments->structureOutput);
break;
case kPseudoAddrSpace_GetFWAddrInfo:
result = ((IOFireWireUserClient*) targetObject)->
addressSpace_GetInfo((UserObjectHandle)arguments->scalarInput[0],
(AddressSpaceInfo *) arguments->structureOutput);
break;
case kPseudoAddrSpace_ClientCommandIsComplete:
result = ((IOFireWireUserClient*) targetObject)->
addressSpace_ClientCommandIsComplete((UserObjectHandle)arguments->scalarInput[0],
(FWClientCommandID)arguments->scalarInput[1],
(IOReturn)arguments->scalarInput[2]);
break;
case kPhysicalAddrSpace_Allocate:
{
UserObjectHandle outAddressSpaceHandle;
result = ((IOFireWireUserClient*) targetObject)->physicalAddressSpace_Create((mach_vm_size_t)arguments->scalarInput[0],
(mach_vm_address_t)arguments->scalarInput[1],
(UInt32)arguments->scalarInput[2],
&outAddressSpaceHandle);
arguments->scalarOutput[0] = (uint64_t) outAddressSpaceHandle;
}
break;
case kPhysicalAddrSpace_GetSegmentCount_d:
{
UInt32 outSegmentCount;
result = ((IOFWUserPhysicalAddressSpace*) targetObject)->getSegmentCount(&outSegmentCount);
arguments->scalarOutput[0] = outSegmentCount;
}
break;
case kPhysicalAddrSpace_GetSegments:
{
UInt32 outSegmentCount;
result = ((IOFireWireUserClient*) targetObject)->physicalAddressSpace_GetSegments((UserObjectHandle)arguments->scalarInput[0],
(UInt32)arguments->scalarInput[1],
(mach_vm_address_t)arguments->scalarInput[2],
&outSegmentCount);
arguments->scalarOutput[0] = outSegmentCount;
}
break;
case kConfigDirectory_Create:
{
UserObjectHandle outDirRef;
result = ((IOFireWireUserClient*) targetObject)->configDirectory_Create(&outDirRef);
arguments->scalarOutput[0] = (uint64_t) outDirRef;
}
break;
case kConfigDirectory_GetKeyType:
{
IOConfigKeyType outType;
result = ((IOFireWireUserClient*) targetObject)->configDirectory_GetKeyType((UserObjectHandle)arguments->scalarInput[0],
(int)arguments->scalarInput[1],
&outType);
arguments->scalarOutput[0] = outType;
}
break;
case kConfigDirectory_GetKeyValue_UInt32:
{
UInt32 outValue;
UserObjectHandle outTextHandle;
UInt32 outTextLength;
result = ((IOFireWireUserClient*) targetObject)->
configDirectory_GetKeyValue_UInt32((UserObjectHandle)arguments->scalarInput[0],
(int)arguments->scalarInput[1],
(UInt32)arguments->scalarInput[2],
&outValue,
&outTextHandle,
&outTextLength);
arguments->scalarOutput[0] = outValue;
arguments->scalarOutput[1] = (uint64_t) outTextHandle;
arguments->scalarOutput[2] = outTextLength;
}
break;
case kConfigDirectory_GetKeyValue_Data:
result = ((IOFireWireUserClient*) targetObject)->
configDirectory_GetKeyValue_Data((UserObjectHandle)arguments->scalarInput[0],
(int)arguments->scalarInput[1],
(UInt32)arguments->scalarInput[2],
(GetKeyValueDataResults *) arguments->structureOutput);
break;
case kConfigDirectory_GetKeyValue_ConfigDirectory:
{
UserObjectHandle outDirHandle;
UserObjectHandle outTextHandle;
UInt32 outTextLength;
result = ((IOFireWireUserClient*) targetObject)->configDirectory_GetKeyValue_ConfigDirectory((UserObjectHandle)arguments->scalarInput[0],
(int)arguments->scalarInput[1],
(UInt32)arguments->scalarInput[2],
&outDirHandle,
&outTextHandle,
&outTextLength);
arguments->scalarOutput[0] = (uint64_t) outDirHandle;
arguments->scalarOutput[1] = (uint64_t) outTextHandle;
arguments->scalarOutput[2] = outTextLength;
}
break;
case kConfigDirectory_GetKeyOffset_FWAddress:
result = ((IOFireWireUserClient*) targetObject)->
configDirectory_GetKeyOffset_FWAddress((UserObjectHandle)arguments->scalarInput[0],
(int)arguments->scalarInput[1],
(UInt32)arguments->scalarInput[2],
(GetKeyOffsetResults *) arguments->structureOutput);
break;
case kConfigDirectory_GetIndexType:
{
IOConfigKeyType outType;
result = ((IOFireWireUserClient*) targetObject)->configDirectory_GetIndexType((UserObjectHandle)arguments->scalarInput[0],
(int)arguments->scalarInput[1],
&outType);
arguments->scalarOutput[0] = (IOConfigKeyType) outType;
}
break;
case kConfigDirectory_GetIndexKey:
{
int outKey;
result = ((IOFireWireUserClient*) targetObject)->configDirectory_GetIndexKey((UserObjectHandle)arguments->scalarInput[0],
(int)arguments->scalarInput[1],
&outKey);
arguments->scalarOutput[0] = outKey;
}
break;
case kConfigDirectory_GetIndexValue_UInt32:
{
UInt32 outKey;
result = ((IOFireWireUserClient*) targetObject)->configDirectory_GetIndexValue_UInt32((UserObjectHandle)arguments->scalarInput[0],
(int)arguments->scalarInput[1],
&outKey);
arguments->scalarOutput[0] = outKey;
}
break;
case kConfigDirectory_GetIndexValue_Data:
{
UserObjectHandle outDataHandle;
IOByteCount outDataLen;
result = ((IOFireWireUserClient*) targetObject)->
configDirectory_GetIndexValue_Data((UserObjectHandle)arguments->scalarInput[0],
(int)arguments->scalarInput[1],
&outDataHandle,
&outDataLen);
arguments->scalarOutput[0] = (uint64_t) outDataHandle;
arguments->scalarOutput[1] = outDataLen;
}
break;
case kConfigDirectory_GetIndexValue_String:
{
UserObjectHandle outTextHandle;
UInt32 outTextLength;
result = ((IOFireWireUserClient*) targetObject)->
configDirectory_GetIndexValue_String((UserObjectHandle)arguments->scalarInput[0],
(int)arguments->scalarInput[1],
&outTextHandle,
&outTextLength);
arguments->scalarOutput[0] = (uint64_t) outTextHandle;
arguments->scalarOutput[1] = outTextLength;
}
break;
case kConfigDirectory_GetIndexValue_ConfigDirectory:
{
UserObjectHandle outDirHandle;
result = ((IOFireWireUserClient*) targetObject)->
configDirectory_GetIndexValue_ConfigDirectory((UserObjectHandle)arguments->scalarInput[0],
(int)arguments->scalarInput[1],
&outDirHandle);
arguments->scalarOutput[0] = (uint64_t) outDirHandle;
}
break;
case kConfigDirectory_GetIndexOffset_FWAddress:
result = ((IOFireWireUserClient*) targetObject)->
configDirectory_GetIndexOffset_FWAddress((UserObjectHandle)arguments->scalarInput[0],
(int)arguments->scalarInput[1],
(FWAddress *) arguments->structureOutput);
break;
case kConfigDirectory_GetIndexOffset_UInt32:
{
UInt32 outValue;
result = ((IOFireWireUserClient*) targetObject)->
configDirectory_GetIndexOffset_UInt32((UserObjectHandle)arguments->scalarInput[0],
(int)arguments->scalarInput[1],
&outValue);
arguments->scalarOutput[0] = outValue;
}
break;
case kConfigDirectory_GetIndexEntry:
{
UInt32 outValue;
result = ((IOFireWireUserClient*) targetObject)->
configDirectory_GetIndexEntry((UserObjectHandle)arguments->scalarInput[0],
(int)arguments->scalarInput[1],
&outValue);
arguments->scalarOutput[0] = outValue;
}
break;
case kConfigDirectory_GetSubdirectories:
{
UserObjectHandle outIteratorHandle;
result = ((IOFireWireUserClient*) targetObject)->
configDirectory_GetSubdirectories((UserObjectHandle)arguments->scalarInput[0],
&outIteratorHandle);
arguments->scalarOutput[0] = (uint64_t) outIteratorHandle;
}
break;
case kConfigDirectory_GetKeySubdirectories:
{
UserObjectHandle outIteratorHandle;
result = ((IOFireWireUserClient*) targetObject)->
configDirectory_GetKeySubdirectories((UserObjectHandle)arguments->scalarInput[0],
(int)arguments->scalarInput[1],
&outIteratorHandle);
arguments->scalarOutput[0] = (uint64_t) outIteratorHandle;
}
break;
case kConfigDirectory_GetType:
{
int outType;
result = ((IOFireWireUserClient*) targetObject)->
configDirectory_GetType((UserObjectHandle)arguments->scalarInput[0],&outType);
arguments->scalarOutput[0] = outType;
}
break;
case kConfigDirectory_GetNumEntries:
{
int outNumEntries;
result = ((IOFireWireUserClient*) targetObject)->
configDirectory_GetNumEntries((UserObjectHandle)arguments->scalarInput[0],&outNumEntries);
arguments->scalarOutput[0] = outNumEntries;
}
break;
case kIsochPort_GetSupported:
{
IOFWSpeed outMaxSpeed;
UInt32 outChanSupportedHi;
UInt32 outChanSupportedLo;
result = ((IOFireWireUserClient*) targetObject)->
localIsochPort_GetSupported((UserObjectHandle)arguments->scalarInput[0],
&outMaxSpeed,
&outChanSupportedHi,
&outChanSupportedLo);
arguments->scalarOutput[0] = outMaxSpeed;
arguments->scalarOutput[1] = outChanSupportedHi;
arguments->scalarOutput[2] = outChanSupportedLo;
}
break;
case kIsochPort_AllocatePort_d:
result = ((IOFWUserLocalIsochPort*) targetObject)->allocatePort((IOFWSpeed)arguments->scalarInput[0],
(UInt32)arguments->scalarInput[1]);
break;
case kIsochPort_ReleasePort_d:
result = ((IOFWUserLocalIsochPort*) targetObject)->releasePort();
break;
case kIsochPort_Start_d:
result = ((IOFWUserLocalIsochPort*) targetObject)->start();
break;
case kIsochPort_Stop_d:
result = ((IOFWUserLocalIsochPort*) targetObject)->stop();
break;
case kLocalIsochPort_Allocate:
result = ((IOFireWireUserClient*) targetObject)->
localIsochPort_Create((LocalIsochPortAllocateParams*) arguments->structureInput,
(UserObjectHandle*) arguments->structureOutput);
break;
case kLocalIsochPort_ModifyJumpDCL_d:
result = ((IOFWUserLocalIsochPort*) targetObject)->modifyJumpDCL((UInt32)arguments->scalarInput[0],
(UInt32)arguments->scalarInput[1]);
break;
case kLocalIsochPort_Notify_d:
if (arguments->scalarInput[0] == kFWNuDCLModifyNotification)
{
IOMemoryDescriptor * userDCLExportDesc = NULL ;
IOReturn error ;
UInt8 *pUserImportDCLBuffer;
userDCLExportDesc = IOMemoryDescriptor::withAddressRange( arguments->scalarInput[2],
arguments->scalarInput[3],
kIODirectionOut,
getOwningTask() ) ;
if ( userDCLExportDesc )
{
error = userDCLExportDesc->prepare() ;
}
else
error = kIOReturnVMError;
if ( !error )
{
pUserImportDCLBuffer = new UInt8[ arguments->scalarInput[3] ] ;
if ( !pUserImportDCLBuffer )
{
error = kIOReturnVMError ;
}
}
if ( !error )
{
unsigned byteCount = userDCLExportDesc->readBytes( 0, (void*)pUserImportDCLBuffer, arguments->scalarInput[3] ) ;
if ( byteCount < arguments->scalarInput[3] )
{
error = kIOReturnVMError ;
}
}
if ( !error )
{
result = ((IOFWUserLocalIsochPort*) targetObject)->userNotify((UInt32)arguments->scalarInput[0],
(UInt32)arguments->scalarInput[1],
(void *) pUserImportDCLBuffer,
arguments->scalarInput[3]);
userDCLExportDesc->complete() ;
userDCLExportDesc->release();
delete [] pUserImportDCLBuffer;
}
else
{
result = kIOReturnVMError;
}
}
else
result = ((IOFWUserLocalIsochPort*) targetObject)->
userNotify((UInt32)arguments->scalarInput[0],
(UInt32)arguments->scalarInput[1],
(void *) arguments->structureInput,
arguments->structureInputSize);
break;
case kLocalIsochPort_SetChannel:
result = ((IOFireWireUserClient*) targetObject)->
localIsochPort_SetChannel((UserObjectHandle)arguments->scalarInput[0],
(UserObjectHandle)arguments->scalarInput[1]);
break;
case kIsochChannel_Allocate:
{
UserObjectHandle outChannelHandle;
result = ((IOFireWireUserClient*) targetObject)->
isochChannel_Create((bool)arguments->scalarInput[0],
(UInt32)arguments->scalarInput[1],
(IOFWSpeed)arguments->scalarInput[2],
&outChannelHandle);
arguments->scalarOutput[0] = (uint64_t) outChannelHandle;
}
break;
case kIsochChannel_UserAllocateChannelBegin:
{
UInt32 outSpeed;
UInt32 outChannel;
result = ((IOFireWireUserClient*) targetObject)->
isochChannel_AllocateChannelBegin((UserObjectHandle)arguments->scalarInput[0],
(UInt32)arguments->scalarInput[1],
(UInt32)arguments->scalarInput[2],
(UInt32)arguments->scalarInput[3],
&outSpeed,
&outChannel);
arguments->scalarOutput[0] = outSpeed;
arguments->scalarOutput[1] = outChannel;
}
break;
case kIsochChannel_UserReleaseChannelComplete_d:
result = ((IOFWUserIsochChannel*) targetObject)->releaseChannelComplete();
break;
case kCommand_Cancel_d:
result = ((IOFWCommand*) targetObject)->cancel((IOReturn)arguments->scalarInput[0]);
break;
case kSeize:
result = ((IOFireWireUserClient*) targetObject)->seize((IOOptionBits) arguments->scalarInput[0]);
break;
case kFireLog:
result = ((IOFireWireUserClient*) targetObject)->
firelog((const char*) arguments->structureInput,arguments->structureInputSize);
break;
case kGetBusCycleTime:
{
UInt32 busTime;
UInt32 cycleTime;
result = ((IOFireWireBus*) targetObject)->getBusCycleTime(busTime,cycleTime);
arguments->scalarOutput[0] = busTime;
arguments->scalarOutput[1] = cycleTime;
}
break;
case kGetBusGeneration:
{
UInt32 outGeneration;
result = ((IOFireWireUserClient*) targetObject)->getBusGeneration(&outGeneration);
arguments->scalarOutput[0] = outGeneration;
}
break;
case kGetLocalNodeIDWithGeneration:
{
UInt32 outLocalNodeID;
result = ((IOFireWireUserClient*) targetObject)->
getLocalNodeIDWithGeneration((UInt32)arguments->scalarInput[0],&outLocalNodeID);
arguments->scalarOutput[0] = outLocalNodeID;
}
break;
case kGetRemoteNodeID:
{
UInt32 outRemoteNodeID;
result = ((IOFireWireUserClient*) targetObject)->
getRemoteNodeID((UInt32)arguments->scalarInput[0],&outRemoteNodeID);
arguments->scalarOutput[0] = outRemoteNodeID;
}
break;
case kGetSpeedToNode:
{
UInt32 outSpeed;
result = ((IOFireWireUserClient*) targetObject)->
getSpeedToNode((UInt32)arguments->scalarInput[0],&outSpeed);
arguments->scalarOutput[0] = outSpeed;
}
break;
case kGetSpeedBetweenNodes:
{
UInt32 outSpeed;
result = ((IOFireWireUserClient*) targetObject)->
getSpeedBetweenNodes((UInt32)arguments->scalarInput[0],
(UInt32)arguments->scalarInput[1],
(UInt32)arguments->scalarInput[2],
&outSpeed);
arguments->scalarOutput[0] = outSpeed;
}
break;
case kGetIRMNodeID:
{
UInt32 irmNodeID;
result = ((IOFireWireUserClient*) targetObject)->
getIRMNodeID((UInt32)arguments->scalarInput[0],&irmNodeID);
arguments->scalarOutput[0] = irmNodeID;
}
break;
case kClipMaxRec2K:
result = ((IOFireWireUserClient*) targetObject)->clipMaxRec2K((Boolean) arguments->scalarInput[0]);
break;
case kIsochPort_SetIsochResourceFlags_d:
result = ((IOFWLocalIsochPort*) targetObject)->setIsochResourceFlags((IOFWIsochResourceFlags) arguments->scalarInput[0]);
break;
case kGetSessionRef:
{
IOFireWireSessionRef sessionRef=NULL;
result = ((IOFireWireUserClient*) targetObject)->getSessionRef(&sessionRef);
arguments->scalarOutput[0] = (uint64_t) sessionRef;
}
break;
case kAllocateIRMBandwidth:
result = ((IOFireWireUserClient*) targetObject)->allocateIRMBandwidthInGeneration(arguments->scalarInput[0],arguments->scalarInput[1]);
break;
case kReleaseIRMBandwidth:
result = ((IOFireWireUserClient*) targetObject)->releaseIRMBandwidthInGeneration(arguments->scalarInput[0],arguments->scalarInput[1]);
break;
case kAllocateIRMChannel:
result = ((IOFireWireUserClient*) targetObject)->allocateIRMChannelInGeneration(arguments->scalarInput[0],arguments->scalarInput[1]);
break;
case kReleaseIRMChannel:
result = ((IOFireWireUserClient*) targetObject)->releaseIRMChannelInGeneration(arguments->scalarInput[0],arguments->scalarInput[1]);
break;
case kAsyncStreamListener_Allocate:
result = ((IOFireWireUserClient*) targetObject)->
asyncStreamListener_Create((FWUserAsyncStreamListenerCreateParams*) arguments->structureInput,
(UserObjectHandle*) arguments->structureOutput);
break;
case kAsyncStreamListener_ClientCommandIsComplete:
result = ((IOFireWireUserClient*) targetObject)->asyncStreamListener_ClientCommandIsComplete((UserObjectHandle)arguments->scalarInput[0],
(FWClientCommandID)arguments->scalarInput[1]);
break;
case kAsyncStreamListener_GetOverrunCounter:
{
UInt32 counter = 0;
result = ((IOFireWireUserClient*) targetObject)->
asyncStreamListener_GetOverrunCounter((UserObjectHandle)arguments->scalarInput[0], &counter);
arguments->scalarOutput[0] = counter;
}
break;
case kAsyncStreamListener_SetFlags:
result = ((IOFireWireUserClient*) targetObject)->
asyncStreamListener_SetFlags((UserObjectHandle)arguments->scalarInput[0],
(UInt32)arguments->scalarInput[1]);
break;
case kAsyncStreamListener_GetFlags:
{
UInt32 outFlags;
result = ((IOFireWireUserClient*) targetObject)->
asyncStreamListener_GetFlags((UserObjectHandle)arguments->scalarInput[0], &outFlags);
arguments->scalarOutput[0] = outFlags;
}
break;
case kAsyncStreamListener_TurnOnNotification:
result = ((IOFireWireUserClient*) targetObject)->asyncStreamListener_TurnOnNotification((UserObjectHandle)arguments->scalarInput[0]);
break;
case kAsyncStreamListener_TurnOffNotification:
result = ((IOFireWireUserClient*) targetObject)->asyncStreamListener_TurnOffNotification((UserObjectHandle)arguments->scalarInput[0]);
break;
case kSetAsyncRef_BusReset:
{
result = ((IOFireWireUserClient*) targetObject)->
setAsyncRef_BusReset(arguments->asyncReference,
(mach_vm_address_t)arguments->scalarInput[0],
(io_user_reference_t)arguments->scalarInput[1],
NULL,NULL,NULL,NULL);
}
break;
case kSetAsyncRef_BusResetDone:
{
result = ((IOFireWireUserClient*) targetObject)->
setAsyncRef_BusResetDone(arguments->asyncReference,
(mach_vm_address_t)arguments->scalarInput[0],
(io_user_reference_t)arguments->scalarInput[1],
NULL,NULL,NULL,NULL);
}
break;
case kSetAsyncRef_Packet:
{
result = ((IOFireWireUserClient*) targetObject)->
setAsyncRef_Packet(arguments->asyncReference,
(UserObjectHandle)arguments->scalarInput[0],
(mach_vm_address_t)arguments->scalarInput[1],
(io_user_reference_t)arguments->scalarInput[2],
NULL,NULL,NULL);
}
break;
case kSetAsyncRef_SkippedPacket:
{
result = ((IOFireWireUserClient*) targetObject)->
setAsyncRef_SkippedPacket(arguments->asyncReference,
(UserObjectHandle)arguments->scalarInput[0],
(mach_vm_address_t)arguments->scalarInput[1],
(io_user_reference_t)arguments->scalarInput[2],
NULL,NULL,NULL);
}
break;
case kSetAsyncRef_Read:
{
result = ((IOFireWireUserClient*) targetObject)->
setAsyncRef_Read(arguments->asyncReference,
(UserObjectHandle)arguments->scalarInput[0],
(mach_vm_address_t)arguments->scalarInput[1],
(io_user_reference_t)arguments->scalarInput[2],
NULL,NULL,NULL);
}
break;
case kCommand_Submit:
{
result = ((IOFireWireUserClient*) targetObject)->
userAsyncCommand_Submit(arguments->asyncReference,
(CommandSubmitParams*)arguments->structureInput,
(CommandSubmitResult*)arguments->structureOutput,
(IOByteCount) arguments->structureInputSize,
(IOByteCount*) &arguments->structureOutputSize);
}
break;
case kSetAsyncRef_IsochChannelForceStop:
{
result = ((IOFireWireUserClient*) targetObject)->
setAsyncRef_IsochChannelForceStop(arguments->asyncReference,
(UserObjectHandle)arguments->scalarInput[0]);
}
break;
case kSetAsyncRef_DCLCallProc:
{
result = ((IOFireWireUserClient*) targetObject)->
setAsyncRef_DCLCallProc(arguments->asyncReference,
(UserObjectHandle)arguments->scalarInput[0]);
}
break;
case kSetAsyncStreamRef_Packet:
{
result = ((IOFireWireUserClient*) targetObject)->
setAsyncStreamRef_Packet(arguments->asyncReference,
(UserObjectHandle)arguments->scalarInput[0],
(mach_vm_address_t)arguments->scalarInput[1],
(io_user_reference_t)arguments->scalarInput[2],
NULL,NULL,NULL);
}
break;
case kSetAsyncStreamRef_SkippedPacket:
{
result = ((IOFireWireUserClient*) targetObject)->
setAsyncStreamRef_SkippedPacket(arguments->asyncReference,
(UserObjectHandle)arguments->scalarInput[0],
(mach_vm_address_t)arguments->scalarInput[1],
(io_user_reference_t)arguments->scalarInput[2],
NULL,NULL,NULL);
}
break;
case kIRMAllocation_Allocate:
{
UserObjectHandle outDataHandle;
result = ((IOFireWireUserClient*) targetObject)->irmAllocation_Create(arguments->scalarInput[0],&outDataHandle);
arguments->scalarOutput[0] = (uint64_t) outDataHandle;
}
break;
case kIRMAllocation_AllocateResources:
result = ((IOFireWireUserClient*) targetObject)->irmAllocation_AllocateResources((UserObjectHandle)arguments->scalarInput[0],
arguments->scalarInput[1],
arguments->scalarInput[2]);
break;
case kIRMAllocation_DeallocateResources:
result = ((IOFireWireUserClient*) targetObject)->irmAllocation_DeallocateResources((UserObjectHandle)arguments->scalarInput[0]);
break;
case kIRMAllocation_areResourcesAllocated:
{
UInt8 isochChannel;
UInt32 bandwidthUnits;
result = ((IOFireWireUserClient*) targetObject)->irmAllocation_areResourcesAllocated((UserObjectHandle)arguments->scalarInput[0], &isochChannel , &bandwidthUnits);
arguments->scalarOutput[1] = (uint64_t) isochChannel;
arguments->scalarOutput[2] = (uint64_t) bandwidthUnits;
}
break;
case kIRMAllocation_setDeallocateOnRelease:
((IOFireWireUserClient*) targetObject)->irmAllocation_setDeallocateOnRelease((UserObjectHandle)arguments->scalarInput[0],arguments->scalarInput[1]);
result = kIOReturnSuccess;
break;
case kIRMAllocation_SetRef:
result = ((IOFireWireUserClient*) targetObject)->irmAllocation_setRef(arguments->asyncReference,
(UserObjectHandle)arguments->scalarInput[0],
arguments->scalarInput[1],
arguments->scalarInput[2]);
break;
case kCommandCreateAsync:
{
result = ((IOFireWireUserClient*) targetObject)->
createAsyncCommand( arguments->asyncReference,
(CommandSubmitParams*)arguments->structureInput,
(UserObjectHandle*)arguments->structureOutput );
}
break;
case kVectorCommandCreate:
result = ((IOFireWireUserClient*) targetObject)->createVectorCommand( (UserObjectHandle*)arguments->structureOutput );
break;
case kVectorCommandSubmit:
result = ((IOFWUserVectorCommand*)targetObject)->submit( arguments->asyncReference,
(mach_vm_address_t)arguments->scalarInput[0],
(io_user_reference_t)arguments->scalarInput[1] );
break;
case kVectorCommandSetBuffers:
result = ((IOFWUserVectorCommand*)targetObject)->setBuffers( (mach_vm_address_t)arguments->scalarInput[0],
(mach_vm_size_t)arguments->scalarInput[1],
(mach_vm_address_t)arguments->scalarInput[2],
(mach_vm_size_t)arguments->scalarInput[3] );
break;
case kPHYPacketListenerCreate:
{
UserObjectHandle kernel_ref;
result = ((IOFireWireUserClient*) targetObject)->createPHYPacketListener( (mach_vm_address_t)arguments->scalarInput[0],
&kernel_ref );
arguments->scalarOutput[0] = (uint64_t)kernel_ref;
}
break;
case kPHYPacketListenerSetPacketCallback:
result = ((IOFWUserPHYPacketListener*)targetObject)->setPacketCallback( arguments->asyncReference,
(mach_vm_address_t)arguments->scalarInput[0],
(io_user_reference_t)arguments->scalarInput[1] );
break;
case kPHYPacketListenerSetSkippedCallback:
result = ((IOFWUserPHYPacketListener*)targetObject)->setSkippedCallback( arguments->asyncReference,
(mach_vm_address_t)arguments->scalarInput[0],
(io_user_reference_t)arguments->scalarInput[1] );
break;
case kPHYPacketListenerActivate:
result = ((IOFWUserPHYPacketListener*)targetObject)->activate();
break;
case kPHYPacketListenerDeactivate:
((IOFWUserPHYPacketListener*)targetObject)->deactivate();
result = kIOReturnSuccess;
break;
case kPHYPacketListenerClientCommandIsComplete:
((IOFWUserPHYPacketListener*)targetObject)->clientCommandIsComplete( (FWClientCommandID)arguments->scalarInput[0] );
result = kIOReturnSuccess;
break;
default:
break;
};
return result;
}
IOReturn
IOFireWireUserClient::registerNotificationPort(
mach_port_t port,
UInt32 ,
UInt32 refCon)
{
fNotificationPort = port ;
fNotificationRefCon = refCon ;
return( kIOReturnUnsupported);
}
#pragma mark -
IOReturn
IOFireWireUserClient::
copyUserData (
mach_vm_address_t userBuffer,
mach_vm_address_t kernBuffer,
mach_vm_size_t bytes ) const
{
if( (userBuffer == NULL) || (kernBuffer == NULL) )
{
return kIOReturnNoMemory;
}
if( bytes == 0 )
{
return kIOReturnSuccess;
}
IOMemoryDescriptor * desc = IOMemoryDescriptor::withAddressRange ( userBuffer, bytes, kIODirectionOut,
fTask ) ;
if ( ! desc )
{
ErrorLog ( "Couldn't create descriptor\n" ) ;
return kIOReturnNoMemory ;
}
IOReturn error = desc->prepare () ;
if ( ! error )
{
if ( bytes != desc->readBytes ( 0, (void*)kernBuffer, bytes ) )
error = kIOReturnVMError ;
desc->complete() ;
desc->release() ;
}
return error ;
}
IOReturn
IOFireWireUserClient::copyToUserBuffer (
IOVirtualAddress kernelBuffer,
mach_vm_address_t userBuffer,
IOByteCount bytes,
IOByteCount & bytesCopied )
{
if( (userBuffer == NULL) || (kernelBuffer == NULL) )
{
return kIOReturnNoMemory;
}
if( bytes == 0 )
{
return kIOReturnSuccess;
}
IOMemoryDescriptor * mem = IOMemoryDescriptor::withAddressRange( userBuffer, bytes, kIODirectionIn, fTask ) ;
if ( ! mem )
return kIOReturnNoMemory ;
IOReturn error = mem->prepare () ;
if ( !error )
{
bytesCopied = mem->writeBytes ( 0, (void*)kernelBuffer, bytes ) ;
mem->complete() ;
}
mem->release() ;
return error ;
}
#pragma mark -
#pragma mark OPEN/CLOSE
IOReturn
IOFireWireUserClient::userOpen ()
{
IOReturn error = kIOReturnSuccess ;
IOFireWireNub * provider = OSDynamicCast( IOFireWireNub, getOwner() ) ;
if ( ! provider )
{
ErrorLog( "Couldn't find provider!\b" ) ;
return kIOReturnError ;
}
if ( getOwner()->open( this ) )
{
IOFWUserObjectExporter * exporter = fOwner->getController()->getSessionRefExporter();
error = exporter->addObject( this, NULL, &fSessionRef );
if( error == kIOReturnSuccess )
{
fSelfOpenCount = 1 ;
fOpenClient = this ;
}
}
else
{
ErrorLog( "couldn't open provider\n" ) ;
error = kIOReturnExclusiveAccess ;
}
return error ;
}
IOReturn
IOFireWireUserClient::userOpenWithSessionRef ( IOFireWireLib::UserObjectHandle sessionRef )
{
IOReturn result = kIOReturnSuccess ;
if (getOwner ()->isOpen())
{
IOFWUserObjectExporter * exporter = fOwner->getController()->getSessionRefExporter();
IOService * open_client = (IOService*) exporter->lookupObjectForType( sessionRef, OSTypeID(IOService) );
IOService * client = open_client;
if (!client)
result = kIOReturnBadArgument ;
else
{
while (client != NULL)
{
if (client == getOwner ())
{
fOpenClient = open_client ;
if ( fOpenClient == this )
{
++fSelfOpenCount ;
}
break ;
}
client = client->getProvider() ;
}
}
if( open_client )
{
open_client->release();
open_client = NULL;
}
}
else
result = kIOReturnNotOpen ;
return result ;
}
IOReturn
IOFireWireUserClient::userClose ()
{
IOReturn result = kIOReturnSuccess ;
if ( getProvider() == NULL )
return kIOReturnSuccess ;
if ( fOpenClient == this )
{
if ( !fOwner->isOpen( this ) )
{
result = kIOReturnNotOpen ;
}
else
{
if ( fSelfOpenCount > 0 )
{
if ( --fSelfOpenCount == 0 )
{
IOFWUserObjectExporter * exporter = fOwner->getController()->getSessionRefExporter();
exporter->removeObject( fSessionRef );
fSessionRef = 0;
fOwner->close(this) ;
fOpenClient = NULL ;
}
}
else
{
return kIOReturnNotOpen ;
}
}
}
return result ;
}
#pragma mark -
#pragma mark GENERAL
IOReturn
IOFireWireUserClient::readQuad ( const ReadQuadParams* params, UInt32* outVal )
{
IOReturn err ;
IOFWReadQuadCommand* cmd ;
if ( params->isAbs )
cmd = this->createReadQuadCommand( params->generation, params->addr, outVal, 1, NULL, NULL ) ;
else
{
if ( (cmd = getOwner ()->createReadQuadCommand( params->addr, outVal, 1, NULL, NULL, params->failOnReset )) )
cmd->setGeneration( params->generation ) ;
}
if(!cmd)
return kIOReturnNoMemory;
err = cmd->submit();
if( !err )
err = cmd->getStatus();
cmd->release();
return err;
}
IOReturn
IOFireWireUserClient::read ( const ReadParams* params, IOByteCount* outBytesTransferred )
{
IOReturn err ;
IOMemoryDescriptor * mem ;
IOFWReadCommand* cmd ;
*outBytesTransferred = 0 ;
mem = IOMemoryDescriptor::withAddressRange(params->buf, params->size, kIODirectionIn, fTask);
if(!mem)
{
return kIOReturnNoMemory;
}
{
IOReturn error = mem->prepare() ;
if ( kIOReturnSuccess != error )
{
mem->release() ;
return error ;
}
}
if ( params->isAbs )
cmd = this->createReadCommand( params->generation, params->addr, mem, NULL, NULL ) ;
else
{
if ( (cmd = getOwner ()->createReadCommand( params->addr, mem, NULL, NULL, params->failOnReset )) )
cmd->setGeneration(params->generation) ;
}
if(!cmd)
{
mem->complete() ;
mem->release() ;
return kIOReturnNoMemory;
}
err = mem->prepare() ;
if ( err )
IOLog("%s %u: IOFireWireUserClient::read: prepare failed\n", __FILE__, __LINE__) ;
else
{
err = cmd->submit(); mem->complete() ;
}
if( !err )
err = cmd->getStatus();
*outBytesTransferred = cmd->getBytesTransferred() ;
cmd->release();
mem->release();
return err;
}
IOReturn
IOFireWireUserClient::writeQuad( const WriteQuadParams* params)
{
IOReturn err;
IOFWWriteQuadCommand* cmd ;
if ( params->isAbs )
cmd = this->createWriteQuadCommand( params->generation, params->addr, (UInt32*) & params->val, 1, NULL, NULL ) ;
else
{
cmd = getOwner ()->createWriteQuadCommand( params->addr, (UInt32*)¶ms->val, 1, NULL, NULL, params->failOnReset ) ;
cmd->setGeneration( params->generation ) ;
}
if(!cmd)
return kIOReturnNoMemory;
err = cmd->submit();
if( err )
err = cmd->getStatus();
cmd->release();
return err;
}
IOReturn
IOFireWireUserClient::write( const WriteParams* params, IOByteCount* outBytesTransferred )
{
IOMemoryDescriptor * mem ;
IOFWWriteCommand* cmd ;
*outBytesTransferred = 0 ;
mem = IOMemoryDescriptor::withAddressRange(params->buf, params->size, kIODirectionOut, fTask);
if(!mem)
{
return kIOReturnNoMemory;
}
{
IOReturn error = mem->prepare() ;
if ( kIOReturnSuccess != error )
{
mem->release() ;
return error ;
}
}
if ( params->isAbs )
{
cmd = this->createWriteCommand( params->generation, params->addr, mem, NULL, NULL ) ;
}
else
{
if ( (cmd = getOwner ()->createWriteCommand( params->addr, mem, NULL, NULL, params->failOnReset )) )
cmd->setGeneration( params->generation ) ;
}
if( !cmd )
{
mem->complete() ;
mem->release() ;
return kIOReturnNoMemory;
}
IOReturn error ;
error = cmd->submit();
if( !error )
error = cmd->getStatus();
if ( !error )
*outBytesTransferred = cmd->getBytesTransferred() ;
cmd->release();
mem->complete() ;
mem->release() ;
return error ;
}
IOReturn
IOFireWireUserClient::compareSwap( const CompareSwapParams* params, UInt32* oldVal )
{
IOReturn err ;
IOFWCompareAndSwapCommand* cmd ;
if ( params->size > 2 )
return kIOReturnBadArgument ;
if ( params->isAbs )
{
cmd = this->createCompareAndSwapCommand( params->generation, params->addr, (UInt32*)& params->cmpVal,
(UInt32*)& params->swapVal, params->size, NULL, NULL ) ;
}
else
{
if ( (cmd = getOwner ()->createCompareAndSwapCommand( params->addr, (UInt32*)& params->cmpVal, (UInt32*)& params->swapVal,
params->size, NULL, NULL, params->failOnReset )) )
{
cmd->setGeneration( params->generation ) ;
}
}
if(!cmd)
return kIOReturnNoMemory;
err = cmd->submit();
if( !err )
{
cmd->locked(oldVal) ;
err = cmd->getStatus();
}
cmd->release();
return err ;
}
IOReturn
IOFireWireUserClient::busReset()
{
FWTrace( kFWTUserClient, kTPUserClientBusReset, (uintptr_t)(getOwner()->getController()->getLink()), fUnsafeResets , 0, 0);
if ( fUnsafeResets )
return getOwner ()->getController()->getLink()->resetBus();
return getOwner ()->getController()->resetBus();
}
IOReturn
IOFireWireUserClient::getGenerationAndNodeID(
UInt32* outGeneration,
UInt32* outNodeID) const
{
UInt16 nodeID ;
getOwner ()->getNodeIDGeneration(*outGeneration, nodeID);
if (!getOwner ()->getController()->checkGeneration(*outGeneration))
return kIOReturnNotFound ;
*outNodeID = (UInt32)nodeID ;
return kIOReturnSuccess ;
}
IOReturn
IOFireWireUserClient::getLocalNodeID(
UInt32* outLocalNodeID) const
{
*outLocalNodeID = (UInt32)(getOwner ()->getController()->getLocalNodeID()) ;
return kIOReturnSuccess ;
}
IOReturn
IOFireWireUserClient::getResetTime(
AbsoluteTime* outResetTime) const
{
*outResetTime = *getOwner ()->getController()->getResetTime() ;
return kIOReturnSuccess ;
}
IOReturn
IOFireWireUserClient::releaseUserObject (
UserObjectHandle obj )
{
fExporter->removeObject( obj ) ;
return kIOReturnSuccess ;
}
#pragma mark -
#pragma mark CONVERSION HELPERS
IOReturn
IOFireWireUserClient::getOSStringData (
UserObjectHandle stringHandle,
UInt32 stringLen,
mach_vm_address_t stringBuffer,
UInt32 * outTextLength )
{
*outTextLength = 0 ;
const OSObject * object = fExporter->lookupObject( stringHandle ) ;
if ( !object )
{
return kIOReturnBadArgument ;
}
OSString * string = OSDynamicCast ( OSString, object ) ;
if ( ! string )
{
object->release() ;
return kIOReturnBadArgument ;
}
IOByteCount len = min( stringLen, string->getLength() ) ;
IOByteCount outLen = 0;
IOReturn error = copyToUserBuffer ( (IOVirtualAddress) string->getCStringNoCopy(),
stringBuffer,
len,
outLen ) ;
*outTextLength = (UInt32)outLen;
fExporter->removeObject( stringHandle ) ;
string->release() ;
return error ;
}
IOReturn
IOFireWireUserClient::getOSDataData (
UserObjectHandle dataHandle,
IOByteCount dataLen,
mach_vm_address_t dataBuffer,
IOByteCount* outDataLen)
{
const OSObject * object = fExporter->lookupObject( dataHandle ) ;
if ( !object )
{
return kIOReturnBadArgument ;
}
OSData * data = OSDynamicCast( OSData, object ) ;
if ( !data )
{
object->release() ;
return kIOReturnBadArgument ;
}
IOReturn error = copyToUserBuffer ( (IOVirtualAddress) data->getBytesNoCopy(),
dataBuffer,
min( data->getLength(), dataLen ),
*outDataLen ) ;
fExporter->removeObject( dataHandle ) ;
object->release() ;
return error ;
}
#pragma mark -
#pragma mark LOCAL CONFIG DIRECTORY
IOReturn
IOFireWireUserClient::localConfigDirectory_Create ( UserObjectHandle* outDir )
{
IOLocalConfigDirectory * dir = IOLocalConfigDirectory::create () ;
if ( ! dir )
{
DebugLog( "IOLocalConfigDirectory::create returned NULL\n" ) ;
return kIOReturnNoMemory ;
}
IOReturn error = fExporter->addObject ( dir, (IOFWUserObjectExporter::CleanupFunction)&IOLocalConfigDirectory::exporterCleanup, outDir ) ;
dir->release() ;
return error ;
}
IOReturn
IOFireWireUserClient::localConfigDirectory_addEntry_Buffer (
UserObjectHandle dirHandle,
int key,
char * buffer,
UInt32 kr_size,
const char * descCString,
UInt32 descLen ) const
{
const OSObject * object = fExporter->lookupObject( dirHandle ) ;
if ( !object )
{
return kIOReturnBadArgument ;
}
IOLocalConfigDirectory * dir = OSDynamicCast ( IOLocalConfigDirectory, object ) ;
if ( ! dir )
{
object->release() ;
return kIOReturnBadArgument ;
}
IOReturn error = kIOReturnSuccess ;
OSData * data = OSData::withCapacity( kr_size ) ;
if ( !data )
{
error = kIOReturnNoMemory ;
}
else
{
data->appendBytes( NULL, kr_size ); copyUserData( (IOVirtualAddress)buffer, (IOVirtualAddress)data->getBytesNoCopy(), kr_size ) ;
OSString * desc = NULL ;
if ( descCString )
{
char cStr[ descLen ] ;
copyUserData( (IOVirtualAddress)descCString, (IOVirtualAddress)cStr, descLen ) ;
cStr[ descLen ] = 0 ;
desc = OSString::withCString( cStr ) ;
}
error = dir->addEntry ( key, data, desc ) ;
data->release() ;
}
dir->release() ;
return error ;
}
IOReturn
IOFireWireUserClient::localConfigDirectory_addEntry_UInt32 (
UserObjectHandle dirHandle,
int key,
UInt32 value,
const char * descCString,
UInt32 descLen ) const
{
const OSObject * object = fExporter->lookupObject( dirHandle ) ;
if ( !object )
{
return kIOReturnBadArgument ;
}
IOLocalConfigDirectory * dir = OSDynamicCast ( IOLocalConfigDirectory, object ) ;
if ( ! dir )
{
object->release() ;
return kIOReturnBadArgument ;
}
OSString * desc = NULL ;
if ( descCString )
{
char cStr[ descLen ] ;
copyUserData( (IOVirtualAddress)descCString, (IOVirtualAddress)cStr, descLen ) ;
cStr[ descLen ] = 0 ;
desc = OSString::withCString( cStr ) ;
}
IOReturn error = dir->addEntry(key, value, desc) ;
dir->release() ;
return error ;
}
IOReturn
IOFireWireUserClient::localConfigDirectory_addEntry_FWAddr (
UserObjectHandle dirHandle,
int key,
const char * descCString,
UInt32 descLen,
FWAddress * value ) const
{
const OSObject * object = fExporter->lookupObject( dirHandle ) ;
if ( !object )
{
return kIOReturnBadArgument ;
}
IOLocalConfigDirectory * dir = OSDynamicCast ( IOLocalConfigDirectory, object ) ;
if ( ! dir )
{
object->release() ;
return kIOReturnBadArgument ;
}
OSString * desc = NULL ;
if ( descCString )
{
char cStr[ descLen ] ;
copyUserData( (IOVirtualAddress)descCString, (IOVirtualAddress)cStr, descLen ) ;
cStr[ descLen ] = 0 ;
desc = OSString::withCString( cStr ) ;
}
IOReturn error = dir->addEntry( key, *value, desc ) ;
dir->release() ;
return error ;
}
IOReturn
IOFireWireUserClient::localConfigDirectory_addEntry_UnitDir (
UserObjectHandle dirHandle,
int key,
UserObjectHandle valueHandle,
const char * descCString,
UInt32 descLen ) const
{
IOLocalConfigDirectory * dir ;
{
const OSObject * object = fExporter->lookupObject( dirHandle ) ;
if ( !object )
{
return kIOReturnBadArgument ;
}
dir = OSDynamicCast( IOLocalConfigDirectory, object ) ;
if ( ! dir )
{
object->release() ;
return kIOReturnBadArgument ;
}
}
IOReturn error ;
IOLocalConfigDirectory * value ;
{
const OSObject * object = fExporter->lookupObject( valueHandle ) ;
if ( !object )
{
return kIOReturnBadArgument ;
}
value = OSDynamicCast( IOLocalConfigDirectory, object ) ;
if ( ! value )
{
object->release() ;
error = kIOReturnBadArgument ;
}
else
{
OSString * desc = NULL ;
if ( descCString )
{
char cStr[ descLen ] ;
copyUserData( (IOVirtualAddress)descCString, (IOVirtualAddress)cStr, descLen ) ;
cStr[ descLen ] = 0 ;
desc = OSString::withCString( cStr ) ;
}
error = dir->addEntry( key, value, desc ) ;
value->release() ;
}
}
dir->release() ;
return error ;
}
IOReturn
IOFireWireUserClient::localConfigDirectory_Publish ( UserObjectHandle dirHandle ) const
{
const OSObject * object = fExporter->lookupObject( dirHandle ) ;
if ( !object )
{
return kIOReturnBadArgument ;
}
IOLocalConfigDirectory * dir = OSDynamicCast ( IOLocalConfigDirectory, object ) ;
if ( ! dir )
{
object->release() ;
return kIOReturnBadArgument ;
}
IOReturn error = getOwner ()->getController()->AddUnitDirectory( dir ) ;
dir->release() ;
return error ;
}
IOReturn
IOFireWireUserClient::localConfigDirectory_Unpublish ( UserObjectHandle dirHandle ) const
{
const OSObject * object = fExporter->lookupObject( dirHandle ) ;
if ( !object )
{
return kIOReturnBadArgument ;
}
IOLocalConfigDirectory * dir = OSDynamicCast ( IOLocalConfigDirectory, object ) ;
if ( ! dir )
{
object->release() ;
return kIOReturnBadArgument ;
}
IOReturn error = getOwner ()->getBus()->RemoveUnitDirectory ( dir ) ;
dir->release() ;
return error ;
}
#pragma mark -
#pragma mark ADDRESS SPACES
IOReturn
IOFireWireUserClient::addressSpace_Create (
AddressSpaceCreateParams * params,
UserObjectHandle * outAddressSpaceHandle )
{
IOFWUserPseudoAddressSpace * addressSpace = OSTypeAlloc( IOFWUserPseudoAddressSpace );
if ( addressSpace &&
( params->isInitialUnits ?
!addressSpace->initFixed( this, params ) : !addressSpace->initPseudo( this, params ) ) )
{
return kIOReturnNoMemory ;
}
IOReturn error = addressSpace->activate() ;
if ( !error )
error = fExporter->addObject ( addressSpace,
&IOFWUserPseudoAddressSpace::exporterCleanup,
outAddressSpaceHandle ) ;
if ( error )
addressSpace->deactivate() ;
addressSpace->release() ;
return error ;
}
IOReturn
IOFireWireUserClient::addressSpace_GetInfo (
UserObjectHandle addressSpaceHandle,
AddressSpaceInfo * outInfo )
{
const OSObject * object = fExporter->lookupObject( addressSpaceHandle ) ;
if ( !object )
{
return kIOReturnBadArgument ;
}
IOFWUserPseudoAddressSpace * me = OSDynamicCast( IOFWUserPseudoAddressSpace, object ) ;
if (!me)
{
object->release() ;
return kIOReturnBadArgument ;
}
outInfo->address = me->getBase() ;
me->release() ;
return kIOReturnSuccess ;
}
IOReturn
IOFireWireUserClient::addressSpace_ClientCommandIsComplete (
UserObjectHandle addressSpaceHandle,
FWClientCommandID inCommandID,
IOReturn inResult)
{
const OSObject * object = fExporter->lookupObject( addressSpaceHandle ) ;
if ( !object )
{
return kIOReturnBadArgument ;
}
IOReturn result = kIOReturnSuccess ;
IOFWUserPseudoAddressSpace * me = OSDynamicCast( IOFWUserPseudoAddressSpace, object ) ;
if (!me)
{
object->release() ;
return kIOReturnBadArgument ;
}
me->clientCommandIsComplete ( inCommandID, inResult ) ;
me->release() ;
return result ;
}
IOReturn
IOFireWireUserClient::setAsyncRef_Packet (
OSAsyncReference64 asyncRef,
UserObjectHandle addressSpaceHandle,
mach_vm_address_t inCallback,
io_user_reference_t inUserRefCon,
void*,
void*,
void*)
{
const OSObject * object = fExporter->lookupObject ( addressSpaceHandle ) ;
if ( !object )
{
return kIOReturnBadArgument ;
}
IOFWUserPseudoAddressSpace * me = OSDynamicCast ( IOFWUserPseudoAddressSpace, object ) ;
if ( ! me )
{
object->release() ;
return kIOReturnBadArgument ;
}
if ( inCallback )
super::setAsyncReference64 ( asyncRef, (mach_port_t) asyncRef[0], inCallback, inUserRefCon ) ;
else
asyncRef[0] = 0 ;
me->setAsyncRef_Packet(asyncRef) ;
me->release() ;
return kIOReturnSuccess ;
}
IOReturn
IOFireWireUserClient::setAsyncRef_SkippedPacket(
OSAsyncReference64 asyncRef,
UserObjectHandle inAddrSpaceRef,
mach_vm_address_t inCallback,
io_user_reference_t inUserRefCon,
void*,
void*,
void*)
{
const OSObject * object = fExporter->lookupObject ( inAddrSpaceRef ) ;
if ( !object )
{
return kIOReturnBadArgument ;
}
IOReturn result = kIOReturnSuccess ;
IOFWUserPseudoAddressSpace * me = OSDynamicCast ( IOFWUserPseudoAddressSpace, object ) ;
if ( !me )
{
object->release() ;
result = kIOReturnBadArgument ;
}
if ( kIOReturnSuccess == result )
{
if (inCallback)
super::setAsyncReference64 ( asyncRef, (mach_port_t) asyncRef[0], (mach_vm_address_t) inCallback, (io_user_reference_t)inUserRefCon ) ;
else
asyncRef[0] = 0 ;
me->setAsyncRef_SkippedPacket(asyncRef) ;
}
me->release();
return result ;
}
IOReturn
IOFireWireUserClient::setAsyncRef_Read(
OSAsyncReference64 asyncRef,
UserObjectHandle inAddrSpaceRef,
mach_vm_address_t inCallback,
io_user_reference_t inUserRefCon,
void*,
void*,
void*)
{
const OSObject * object = fExporter->lookupObject ( inAddrSpaceRef ) ;
if ( !object )
{
return kIOReturnBadArgument ;
}
IOReturn result = kIOReturnSuccess ;
IOFWUserPseudoAddressSpace * me = OSDynamicCast ( IOFWUserPseudoAddressSpace, object ) ;
if ( !me )
{
object->release() ;
result = kIOReturnBadArgument ;
}
if ( kIOReturnSuccess == result )
{
if (inCallback)
super::setAsyncReference64 ( asyncRef, (mach_port_t) asyncRef[0], inCallback, inUserRefCon ) ;
else
asyncRef[0] = 0 ;
me->setAsyncRef_Read(asyncRef) ;
}
me->release();
return result ;
}
IOReturn
IOFireWireUserClient::setAsyncRef_BusReset(
OSAsyncReference64 asyncRef,
mach_vm_address_t inCallback,
io_user_reference_t inRefCon,
void*,
void*,
void*,
void*)
{
super::setAsyncReference64 ( asyncRef, (mach_port_t) asyncRef[0], (mach_vm_address_t)inCallback, (io_user_reference_t)inRefCon ) ;
bcopy(asyncRef, fBusResetAsyncNotificationRef, sizeof(OSAsyncReference64)) ;
return kIOReturnSuccess ;
}
IOReturn
IOFireWireUserClient::setAsyncRef_BusResetDone(
OSAsyncReference64 inAsyncRef,
mach_vm_address_t inCallback,
io_user_reference_t inRefCon,
void*,
void*,
void*,
void*)
{
super::setAsyncReference64 ( inAsyncRef, (mach_port_t) inAsyncRef[0], inCallback, (io_user_reference_t)inRefCon ) ;
bcopy(inAsyncRef, fBusResetDoneAsyncNotificationRef, sizeof(OSAsyncReference64)) ;
return kIOReturnSuccess ;
}
#pragma mark -
#pragma mark PHYSICAL ADDRESS SPACES
IOReturn
IOFireWireUserClient::physicalAddressSpace_Create (
mach_vm_size_t size,
mach_vm_address_t backingStore,
UInt32 flags,
UserObjectHandle * outAddressSpaceHandle )
{
IOMemoryDescriptor* mem = IOMemoryDescriptor::withAddressRange( backingStore, size, kIODirectionOutIn, fTask ) ;
if ( ! mem )
{
DebugLog("couldn't get memory descriptor for physical address space memory\n") ;
return kIOReturnNoMemory ;
}
IOReturn error = mem->prepare( kIODirectionPrepareToPhys32 );
if ( error )
{
DebugLog("couldn't prepare address space memory descriptor\n") ;
mem->release() ;
return error ;
}
IOFWUserPhysicalAddressSpace * addrSpace = OSTypeAlloc( IOFWUserPhysicalAddressSpace );
if ( addrSpace && !addrSpace->initWithDesc( getOwner()->getController(), mem ) )
{
addrSpace->release() ;
addrSpace = NULL ;
}
if ( ! addrSpace )
{
error = kIOReturnNoMemory ;
}
else
{
error = addrSpace->activate() ;
if ( ! error )
error = fExporter->addObject( addrSpace,
&IOFWUserPhysicalAddressSpace::exporterCleanup,
outAddressSpaceHandle );
addrSpace->release () ; }
mem->release() ;
return error ;
}
IOReturn
IOFireWireUserClient::physicalAddressSpace_GetSegments (
UserObjectHandle addressSpaceHandle,
UInt32 inSegmentCount,
mach_vm_address_t outSegments,
UInt32* outSegmentCount)
{
const OSObject * object = fExporter->lookupObject( addressSpaceHandle ) ;
if ( !object )
{
return kIOReturnBadArgument ;
}
IOFWUserPhysicalAddressSpace* addressSpace = OSDynamicCast( IOFWUserPhysicalAddressSpace, object ) ;
if ( ! addressSpace )
{
object->release() ;
return kIOReturnBadArgument ;
}
UInt32 segmentCount ;
IOReturn error = addressSpace->getSegmentCount( &segmentCount ) ;
if ( error == kIOReturnSuccess )
{
segmentCount = min( segmentCount, inSegmentCount ) ;
FWPhysicalSegment32 * segments = new FWPhysicalSegment32[ segmentCount ] ;
if ( !segments )
{
error = kIOReturnNoMemory ;
}
if ( !error )
{
error = addressSpace->getSegments( & segmentCount, segments ) ;
}
if ( ! error )
{
IOByteCount bytesCopied ;
error = copyToUserBuffer( (IOVirtualAddress)segments, outSegments, sizeof( FWPhysicalSegment32 ) * segmentCount, bytesCopied ) ;
*outSegmentCount = bytesCopied / sizeof( FWPhysicalSegment32 ) ;
}
delete[] segments ;
}
addressSpace->release() ;
return error ;
}
#pragma mark
#pragma mark CONFIG DIRECTORY
IOReturn
IOFireWireUserClient::configDirectory_Create ( UserObjectHandle * outDirRef )
{
IOConfigDirectory * configDir ;
IOReturn error = getOwner ()->getConfigDirectoryRef ( configDir );
if ( error )
return error ;
if ( !configDir )
error = kIOReturnNoMemory ;
else
{
error = fExporter->addObject ( configDir, NULL, outDirRef ) ;
configDir->release () ;
}
return error ;
}
IOReturn
IOFireWireUserClient::configDirectory_GetKeyType (
UserObjectHandle dirHandle,
int key,
IOConfigKeyType * outType) const
{
const OSObject * object = fExporter->lookupObject( dirHandle ) ;
if ( !object )
{
return kIOReturnBadArgument ;
}
IOConfigDirectory * dir = OSDynamicCast( IOConfigDirectory, object ) ;
if ( !dir )
{
object->release() ;
return kIOReturnBadArgument ;
}
IOReturn error = dir->getKeyType(key, *outType) ;
dir->release() ;
return error ;
}
IOReturn
IOFireWireUserClient::configDirectory_GetKeyValue_UInt32 (
UserObjectHandle dirHandle,
int key,
UInt32 wantText,
UInt32 * outValue,
UserObjectHandle * outTextHandle,
UInt32 * outTextLength ) const
{
const OSObject * object = fExporter->lookupObject( dirHandle ) ;
if ( !object )
{
return kIOReturnBadArgument ;
}
IOConfigDirectory * dir = OSDynamicCast ( IOConfigDirectory, object ) ;
if ( ! dir )
{
object->release() ;
return kIOReturnBadArgument ;
}
OSString * outString = NULL ;
IOReturn error = dir->getKeyValue( key, *outValue, ((bool)wantText) ? & outString : NULL ) ;
if ( outString && !error )
{
error = fExporter->addObject( outString, NULL, outTextHandle ) ;
outString->release () ;
if ( ! error )
*outTextLength = outString->getLength() ;
}
dir->release() ;
return error ;
}
IOReturn
IOFireWireUserClient::configDirectory_GetKeyValue_Data (
UserObjectHandle dirHandle,
int key,
UInt32 wantText,
GetKeyValueDataResults * results ) const
{
const OSObject * object = fExporter->lookupObject( dirHandle ) ;
if ( !object )
{
return kIOReturnBadArgument ;
}
IOConfigDirectory * dir = OSDynamicCast ( IOConfigDirectory, object ) ;
if ( ! dir )
{
object->release() ;
return kIOReturnBadArgument ;
}
OSData * outData = NULL ;
OSString * outText = NULL ;
IOReturn error = dir->getKeyValue ( key, outData, ((bool)wantText) ? & outText : NULL ) ;
if ( outText )
{
if ( ! error )
{
error = fExporter->addObject( outText, NULL, &results->text ) ;
results->textLength = outText->getLength() ;
}
outText->release() ;
}
if ( outData )
{
if ( ! error )
{
error = fExporter->addObject( outData, NULL, &results->data ) ;
results->dataLength = outData->getLength() ;
}
outData->release() ;
}
dir->release() ;
return error ;
}
IOReturn
IOFireWireUserClient::configDirectory_GetKeyValue_ConfigDirectory(
UserObjectHandle dirHandle,
int key,
UInt32 wantText,
UserObjectHandle * outDirHandle,
UserObjectHandle * outTextHandle,
UInt32 * outTextLength ) const
{
const OSObject * object = fExporter->lookupObject( dirHandle ) ;
if ( !object )
{
return kIOReturnBadArgument ;
}
IOConfigDirectory * dir = OSDynamicCast ( IOConfigDirectory, object ) ;
if ( ! dir )
{
object->release() ;
return kIOReturnBadArgument ;
}
OSString * outText = NULL ;
IOConfigDirectory * outDir = NULL ;
IOReturn error = dir->getKeyValue ( key, outDir, ((bool)wantText) ? & outText : NULL ) ;
if ( outText )
{
if ( ! error )
{
*outTextLength = outText->getLength() ;
error = fExporter->addObject( outText, NULL, outTextHandle ) ;
}
outText->release() ;
}
if ( outDir )
{
if ( ! error )
error = fExporter->addObject( outDir, NULL, outDirHandle ) ;
outDir->release() ;
}
dir->release() ;
return error ;
}
IOReturn
IOFireWireUserClient::configDirectory_GetKeyOffset_FWAddress (
UserObjectHandle dirHandle,
int key,
UInt32 wantText,
GetKeyOffsetResults * results ) const
{
const OSObject * object = fExporter->lookupObject( dirHandle ) ;
if ( !object )
{
return kIOReturnBadArgument ;
}
IOConfigDirectory * dir = OSDynamicCast ( IOConfigDirectory, object ) ;
if ( ! dir )
{
object->release() ;
return kIOReturnBadArgument ;
}
OSString * outText = NULL ;
IOReturn error = dir->getKeyOffset ( key, results->address, ((bool)wantText) ? & outText : NULL) ;
if ( outText )
{
if ( ! error )
{
results->length = outText->getLength() ;
error = fExporter->addObject( outText, NULL, &results->text ) ;
}
outText->release() ;
}
dir->release() ;
return error ;
}
IOReturn
IOFireWireUserClient::configDirectory_GetIndexType (
UserObjectHandle dirHandle,
int index,
IOConfigKeyType* outType ) const
{
const OSObject * object = fExporter->lookupObject( dirHandle ) ;
if ( !object )
{
return kIOReturnBadArgument ;
}
IOConfigDirectory * dir = OSDynamicCast ( IOConfigDirectory, object ) ;
if ( ! dir )
{
object->release() ;
return kIOReturnBadArgument ;
}
IOReturn error = dir->getIndexType(index, *outType) ;
dir->release() ;
return error ;
}
IOReturn
IOFireWireUserClient::configDirectory_GetIndexKey (
UserObjectHandle dirHandle,
int index,
int * outKey ) const
{
const OSObject * object = fExporter->lookupObject( dirHandle ) ;
if ( !object )
{
return kIOReturnBadArgument ;
}
IOConfigDirectory * dir = OSDynamicCast ( IOConfigDirectory, object ) ;
if ( ! dir )
{
object->release() ;
return kIOReturnBadArgument ;
}
IOReturn error = dir->getIndexKey(index, *outKey) ;
dir->release() ;
return error ;
}
IOReturn
IOFireWireUserClient::configDirectory_GetIndexValue_UInt32 (
UserObjectHandle dirHandle,
int index,
UInt32* outKey ) const
{
const OSObject * object = fExporter->lookupObject( dirHandle ) ;
if ( !object )
{
return kIOReturnBadArgument ;
}
IOConfigDirectory * dir = OSDynamicCast ( IOConfigDirectory, object ) ;
if ( ! dir )
{
object->release() ;
return kIOReturnBadArgument ;
}
IOReturn error = dir->getIndexValue(index, *outKey) ;
dir->release() ;
return error ;
}
IOReturn
IOFireWireUserClient::configDirectory_GetIndexValue_Data (
UserObjectHandle dirHandle,
int index,
UserObjectHandle * outDataHandle,
IOByteCount * outDataLen ) const
{
const OSObject * object = fExporter->lookupObject( dirHandle ) ;
if ( !object )
{
return kIOReturnBadArgument ;
}
IOConfigDirectory * dir = OSDynamicCast ( IOConfigDirectory, object ) ;
if ( ! dir )
{
object->release() ;
return kIOReturnBadArgument ;
}
OSData * outData = NULL ;
IOReturn error = dir->getIndexValue( index, outData ) ;
if ( !error && outData )
{
error = fExporter->addObject( outData, NULL, outDataHandle ) ;
*outDataLen = outData->getLength() ;
outData->release() ;
}
dir->release() ;
return error ;
}
IOReturn
IOFireWireUserClient::configDirectory_GetIndexValue_String (
UserObjectHandle dirHandle,
int index,
UserObjectHandle * outTextHandle,
UInt32 * outTextLength ) const
{
InfoLog("IOFireWireUserClient<%p>::configDirectory_GetIndexValue_String, index=%d, outTextHandle=%p\n", this ) ;
const OSObject * object = fExporter->lookupObject( dirHandle ) ;
if ( !object )
{
DebugLog("IOFireWireUserClient<%p>::configDirectory_GetIndexValue_String() -- dir handle is invalid\n", this ) ;
return kIOReturnBadArgument ;
}
IOConfigDirectory * dir = OSDynamicCast ( IOConfigDirectory, object ) ;
if ( ! dir )
{
DebugLog("IOFireWireUserClient<%p>::configDirectory_GetIndexValue_String() -- dir handle is not a config directory object!\n", this ) ;
object->release() ;
return kIOReturnBadArgument ;
}
OSString * outText = NULL ;
IOReturn error = dir->getIndexValue( index, outText ) ;
InfoLog("a. IOFireWireUserClient<%p>::configDirectory_GetIndexValue_String error=%x\n", this, error ) ;
if ( !error && outText )
{
*outTextLength = outText->getLength() ;
error = fExporter->addObject( outText, NULL, outTextHandle ) ;
outText->release() ;
}
dir->release() ;
return error ;
}
IOReturn
IOFireWireUserClient::configDirectory_GetIndexValue_ConfigDirectory (
UserObjectHandle dirHandle,
int index,
UserObjectHandle * outDirHandle ) const
{
const OSObject * object = fExporter->lookupObject( dirHandle ) ;
if ( !object )
{
return kIOReturnBadArgument ;
}
IOConfigDirectory * dir = OSDynamicCast ( IOConfigDirectory, object ) ;
if ( ! dir )
{
object->release() ;
return kIOReturnBadArgument ;
}
IOConfigDirectory * outDir = NULL ;
IOReturn error = dir->getIndexValue( index, outDir ) ;
if ( ! error && outDir )
{
error = fExporter->addObject ( outDir, NULL, outDirHandle ) ;
outDir->release() ;
}
dir->release() ;
return error ;
}
IOReturn
IOFireWireUserClient::configDirectory_GetIndexOffset_FWAddress (
UserObjectHandle dirHandle,
int index,
FWAddress * outAddress ) const
{
const OSObject * object = fExporter->lookupObject( dirHandle ) ;
if ( !object )
{
return kIOReturnBadArgument ;
}
IOConfigDirectory * dir = OSDynamicCast ( IOConfigDirectory, object ) ;
if ( ! dir )
{
object->release() ;
return kIOReturnBadArgument ;
}
IOReturn result = dir->getIndexOffset( index, *outAddress ) ;
dir->release() ;
return result ;
}
IOReturn
IOFireWireUserClient::configDirectory_GetIndexOffset_UInt32 (
UserObjectHandle dirHandle,
int index,
UInt32* outValue) const
{
const OSObject * object = fExporter->lookupObject( dirHandle ) ;
if ( !object )
{
return kIOReturnBadArgument ;
}
IOConfigDirectory * dir = OSDynamicCast ( IOConfigDirectory, object ) ;
if ( ! dir )
{
object->release() ;
return kIOReturnBadArgument ;
}
IOReturn error = dir->getIndexOffset(index, *outValue) ;
dir->release() ;
return error ;
}
IOReturn
IOFireWireUserClient::configDirectory_GetIndexEntry (
UserObjectHandle dirHandle,
int index,
UInt32* outValue) const
{
const OSObject * object = fExporter->lookupObject( dirHandle ) ;
if ( !object )
{
return kIOReturnBadArgument ;
}
IOConfigDirectory * dir = OSDynamicCast ( IOConfigDirectory, object ) ;
if ( ! dir )
{
object->release() ;
return kIOReturnBadArgument ;
}
IOReturn error = dir->getIndexEntry(index, *outValue) ;
dir->release() ;
return error ;
}
IOReturn
IOFireWireUserClient::configDirectory_GetSubdirectories (
UserObjectHandle dirHandle,
UserObjectHandle* outIteratorHandle ) const
{
const OSObject * object = fExporter->lookupObject( dirHandle ) ;
if ( !object )
{
return kIOReturnBadArgument ;
}
IOConfigDirectory * dir = OSDynamicCast ( IOConfigDirectory, object ) ;
if ( ! dir )
{
object->release() ;
return kIOReturnBadArgument ;
}
OSIterator * outIterator = NULL ;
IOReturn error = dir->getSubdirectories( outIterator ) ;
if ( outIterator )
{
if ( ! error )
error = fExporter->addObject( outIterator, NULL, outIteratorHandle ) ;
outIterator->release () ;
}
dir->release() ;
return error ;
}
IOReturn
IOFireWireUserClient::configDirectory_GetKeySubdirectories (
UserObjectHandle dirHandle ,
int key,
UserObjectHandle* outIteratorHandle ) const
{
const OSObject * object = fExporter->lookupObject( dirHandle ) ;
if ( !object )
{
return kIOReturnBadArgument ;
}
IOConfigDirectory * dir = OSDynamicCast ( IOConfigDirectory, object ) ;
if ( ! dir )
{
object->release() ;
return kIOReturnBadArgument ;
}
OSIterator * outIterator = NULL ;
IOReturn error = dir->getKeySubdirectories( key, outIterator ) ;
if ( outIterator )
{
if ( ! error )
error = fExporter->addObject( outIterator, NULL, outIteratorHandle ) ;
outIterator->release() ;
}
dir->release() ;
return error ;
}
IOReturn
IOFireWireUserClient::configDirectory_GetType (
UserObjectHandle dirHandle,
int* outType) const
{
const OSObject * object = fExporter->lookupObject( dirHandle ) ;
if ( !object )
{
return kIOReturnBadArgument ;
}
IOConfigDirectory * dir = OSDynamicCast ( IOConfigDirectory, object ) ;
if ( ! dir )
{
object->release() ;
return kIOReturnBadArgument ;
}
*outType = dir->getType();
dir->release() ;
return kIOReturnSuccess ;
}
IOReturn
IOFireWireUserClient::configDirectory_GetNumEntries (
UserObjectHandle dirHandle,
int* outNumEntries) const
{
const OSObject * object = fExporter->lookupObject( dirHandle ) ;
if ( !object )
{
return kIOReturnBadArgument ;
}
IOConfigDirectory * dir = OSDynamicCast ( IOConfigDirectory, object ) ;
if ( ! dir )
{
object->release() ;
return kIOReturnBadArgument ;
}
*outNumEntries = dir->getNumEntries() ;
dir->release() ;
return kIOReturnSuccess ;
}
#pragma mark -
#pragma mark LOCAL ISOCH PORT
IOReturn
IOFireWireUserClient::localIsochPort_GetSupported(
UserObjectHandle portHandle,
IOFWSpeed* outMaxSpeed,
UInt32* outChanSupportedHi,
UInt32* outChanSupportedLo) const
{
const OSObject * object = fExporter->lookupObject( portHandle ) ;
if ( !object )
{
return kIOReturnBadArgument ;
}
IOFWUserLocalIsochPort * port = OSDynamicCast ( IOFWUserLocalIsochPort, object ) ;
if ( ! port )
{
object->release() ;
return kIOReturnBadArgument ;
}
UInt64 chanSupported ;
IOReturn result = kIOReturnSuccess ;
result = port->getSupported( *outMaxSpeed, chanSupported ) ;
*outChanSupportedHi = (UInt32)( chanSupported >> 32 ) ;
*outChanSupportedLo = (UInt32)( chanSupported & 0xFFFFFFFF ) ;
port->release() ;
return result ;
}
IOReturn
IOFireWireUserClient::localIsochPort_Create (
LocalIsochPortAllocateParams* params,
UserObjectHandle* outPortHandle )
{
IOFWUserLocalIsochPort * port = OSTypeAlloc( IOFWUserLocalIsochPort );
if ( port && ! port->initWithUserDCLProgram( params, *this, *getOwner()->getController() ) )
{
port->release() ;
port = NULL ;
}
if ( !port )
{
DebugLog( "couldn't create local isoch port\n" ) ;
return kIOReturnError ;
}
IOReturn error = fExporter->addObject( port,
&IOFWUserLocalIsochPort::exporterCleanup,
outPortHandle ) ;
port->release() ;
return error ;
}
IOReturn
IOFireWireUserClient::localIsochPort_SetChannel (
UserObjectHandle portHandle,
UserObjectHandle channelHandle )
{
InfoLog("IOFireWireUserClient<%p>::localIsochPort_SetChannel\n", this ) ;
const OSObject * object1 = fExporter->lookupObject( portHandle ) ;
IOFWUserLocalIsochPort * port = OSDynamicCast ( IOFWUserLocalIsochPort, object1 ) ;
IOReturn error = kIOReturnSuccess ;
if ( !port )
{
error = kIOReturnBadArgument ;
}
const OSObject * object2 = NULL ;
IOFWUserIsochChannel * channel = NULL ;
if ( !error )
{
object2 = fExporter->lookupObject( channelHandle ) ;
channel = OSDynamicCast( IOFWUserIsochChannel, object2 ) ;
if ( !channel )
{
error = kIOReturnBadArgument ;
}
}
if ( !error )
{
IODCLProgram * program = port->getProgramRef() ;
if ( program )
{
program->setForceStopProc( (IOFWIsochChannel::ForceStopNotificationProc*)&IOFWUserIsochChannel::isochChannel_ForceStopHandler, channel, channel ) ;
program->release() ;
}
}
if ( object1 )
{
object1->release() ;
}
if ( object2 )
{
object2->release() ;
}
return error ;
}
IOReturn
IOFireWireUserClient::setAsyncRef_DCLCallProc (
OSAsyncReference64 asyncRef,
UserObjectHandle portHandle )
{
InfoLog("IOFireWireUserClient<%p>::setAsyncRef_DCLCallProc\n", this ) ;
const OSObject * object = fExporter->lookupObject( portHandle ) ;
if ( !object )
{
return kIOReturnBadArgument ;
}
IOFWUserLocalIsochPort * port = OSDynamicCast( IOFWUserLocalIsochPort, object ) ;
if ( ! port )
{
object->release() ;
return kIOReturnBadArgument ;
}
IOReturn error = port->setAsyncRef_DCLCallProc( asyncRef ) ;
port->release() ;
return error ;
}
#pragma mark -
#pragma mark ISOCH CHANNEL
IOReturn
IOFireWireUserClient::isochChannel_Create (
bool inDoIRM,
UInt32 inPacketSize,
IOFWSpeed inPrefSpeed,
UserObjectHandle * outChannelHandle )
{
IOReturn error = kIOReturnSuccess ;
IOFWUserIsochChannel * channel = OSTypeAlloc( IOFWUserIsochChannel );
if ( channel )
{
if ( channel->init( getOwner()->getController(), inDoIRM, inPacketSize, inPrefSpeed ) )
{
fExporter->addObject( channel,
(IOFWUserObjectExporter::CleanupFunction) & IOFWUserIsochChannel::s_exporterCleanup,
outChannelHandle ) ;
}
channel->release() ; }
else
{
error = kIOReturnNoMemory ;
}
return error ;
}
IOReturn
IOFireWireUserClient::isochChannel_AllocateChannelBegin(
UserObjectHandle channelRef,
UInt32 speed,
UInt32 chansHi,
UInt32 chansLo,
UInt32 * outSpeed,
UInt32 * outChannel )
{
InfoLog("IOFireWireUserClient<%p>::isochChannel_AllocateChannelBegin\n", this ) ;
IOReturn error = kIOReturnSuccess ;
const OSObject * object = fExporter->lookupObject( channelRef ) ;
IOFWUserIsochChannel * channel = OSDynamicCast( IOFWUserIsochChannel, object ) ;
if ( ! channel )
{
error = kIOReturnBadArgument ;
}
if ( !error )
{
UInt64 allowedChans = ((UInt64)chansHi << 32) | (UInt64)chansLo ;
error = channel->allocateChannelBegin( (IOFWSpeed)speed, allowedChans, outChannel ) ;
*outSpeed = speed;
}
if ( object )
{
object->release() ; }
return error ;
}
IOReturn
IOFireWireUserClient::setAsyncRef_IsochChannelForceStop(
OSAsyncReference64 inAsyncRef,
UserObjectHandle channelRef )
{
IOReturn error = kIOReturnSuccess;
const OSObject * object = fExporter->lookupObject( channelRef ) ;
IOFWUserIsochChannel * channel = OSDynamicCast( IOFWUserIsochChannel, object ) ;
if ( !channel )
{
#if __LP64__
DebugLog("IOFireWireUserClient<%p>::setAsyncRef_IsochChannelForceStop() -- invalid channel ref %llx\n", this, (UInt64)channelRef ) ;
#else
DebugLog("IOFireWireUserClient<%p>::setAsyncRef_IsochChannelForceStop() -- invalid channel ref %lx\n", this, (UInt32)channelRef ) ;
#endif
error = kIOReturnBadArgument ;
}
io_user_reference_t * asyncRef = NULL;
if( error == kIOReturnSuccess )
{
asyncRef = new io_user_reference_t[ kOSAsyncRefCount ] ;
if ( !asyncRef )
{
error = kIOReturnNoMemory ;
}
}
if( error == kIOReturnSuccess )
{
bcopy( inAsyncRef, asyncRef, sizeof( OSAsyncReference64 ) ) ;
io_user_reference_t * oldAsyncRef = channel->getUserAsyncRef() ;
channel->setUserAsyncRef( asyncRef ) ;
delete [] oldAsyncRef ;
}
if( channel != NULL )
{
channel->release();
}
return error;
}
#pragma mark -
#pragma mark COMMAND OBJECTS
IOReturn
IOFireWireUserClient::createAsyncCommand( OSAsyncReference64 asyncRef,
CommandSubmitParams * params,
UserObjectHandle * kernel_ref )
{
IOReturn status = kIOReturnSuccess;
IOFWUserCommand * cmd = NULL;
if( status == kIOReturnSuccess )
{
cmd = IOFWUserCommand::withSubmitParams( params, this );
if( !cmd )
status = kIOReturnNoMemory;
}
if( status == kIOReturnSuccess )
{
status = fExporter->addObject( cmd, NULL, kernel_ref );
}
if( status == kIOReturnSuccess )
{
cmd->setRefCon( (mach_vm_address_t)params->refCon);
}
if( status == kIOReturnSuccess )
{
setAsyncReference64( asyncRef, (mach_port_t) asyncRef[0], (mach_vm_address_t)params->callback, (io_user_reference_t)params->refCon);
cmd->setAsyncReference64( asyncRef );
}
if( cmd )
{
cmd->release(); cmd = NULL;
}
return status;
}
IOReturn
IOFireWireUserClient::userAsyncCommand_Submit(
OSAsyncReference64 asyncRef,
CommandSubmitParams * params,
CommandSubmitResult * outResult,
IOByteCount paramsSize,
IOByteCount * outResultSize)
{
IOFWUserCommand * cmd = NULL ;
IOReturn error = kIOReturnSuccess ;
if ( params->kernCommandRef )
{
const OSObject * object = fExporter->lookupObject( params->kernCommandRef ) ;
if ( !object )
{
error = kIOReturnBadArgument ;
}
else
{
cmd = OSDynamicCast( IOFWUserCommand, object ) ;
if ( ! cmd )
{
object->release() ;
error = kIOReturnBadArgument ;
}
}
}
else
{
cmd = IOFWUserCommand::withSubmitParams( params, this ) ;
if ( ! cmd )
error = kIOReturnNoMemory ;
else
{
UserObjectHandle command_ref;
error = fExporter->addObject( cmd, NULL, &command_ref );
outResult->kernCommandRef = command_ref;
}
}
if ( cmd )
{
if ( !error )
{
super::setAsyncReference64( asyncRef, (mach_port_t) asyncRef[0], (mach_vm_address_t)params->callback, (io_user_reference_t)params->refCon) ;
cmd->setAsyncReference64( asyncRef ) ;
cmd->setRefCon( (mach_vm_address_t)params->refCon);
error = cmd->submit( params, outResult ) ;
}
cmd->release() ; }
return error ;
}
IOFWReadCommand*
IOFireWireUserClient::createReadCommand(
UInt32 generation,
FWAddress devAddress,
IOMemoryDescriptor* hostMem,
FWDeviceCallback completion,
void* refcon ) const
{
IOFWReadCommand* result = OSTypeAlloc( IOFWReadCommand );
if ( result && !result->initAll( getOwner ()->getController(), generation, devAddress, hostMem, completion, refcon ) )
{
result->release() ;
result = NULL ;
}
return result ;
}
IOFWReadQuadCommand*
IOFireWireUserClient::createReadQuadCommand(
UInt32 generation,
FWAddress devAddress,
UInt32 * quads,
int numQuads,
FWDeviceCallback completion,
void * refcon ) const
{
IOFWReadQuadCommand* result = OSTypeAlloc( IOFWReadQuadCommand );
if ( result && !result->initAll( getOwner ()->getController(), generation, devAddress, quads, numQuads, completion, refcon ) )
{
result->release() ;
return NULL ;
}
return result ;
}
IOFWWriteCommand*
IOFireWireUserClient::createWriteCommand(
UInt32 generation,
FWAddress devAddress,
IOMemoryDescriptor* hostMem,
FWDeviceCallback completion,
void* refcon ) const
{
IOFWWriteCommand* result = OSTypeAlloc( IOFWWriteCommand );
if ( result && !result->initAll( getOwner ()->getController(), generation, devAddress, hostMem, completion, refcon ) )
{
result->release() ;
return NULL ;
}
return result ;
}
IOFWWriteQuadCommand*
IOFireWireUserClient::createWriteQuadCommand(
UInt32 generation,
FWAddress devAddress,
UInt32 * quads,
int numQuads,
FWDeviceCallback completion,
void * refcon ) const
{
IOFWWriteQuadCommand* result = OSTypeAlloc( IOFWWriteQuadCommand );
if ( result && !result->initAll( getOwner ()->getController(), generation, devAddress, quads, numQuads, completion, refcon ) )
{
result->release() ;
return NULL ;
}
return result ;
}
IOFWCompareAndSwapCommand*
IOFireWireUserClient::createCompareAndSwapCommand(
UInt32 generation,
FWAddress devAddress,
const UInt32 * cmpVal,
const UInt32 * newVal,
int size,
FWDeviceCallback completion,
void * refcon ) const
{
IOFWCompareAndSwapCommand* result = OSTypeAlloc( IOFWCompareAndSwapCommand );
if ( result && !result->initAll( getOwner ()->getController(), generation, devAddress, cmpVal, newVal, size, completion, refcon ) )
{
result->release() ;
return NULL ;
}
return result ;
}
#pragma mark -
IOReturn
IOFireWireUserClient::firelog( const char* string, IOByteCount bufSize ) const
{
#if FIRELOG
FireLog( string ) ;
#endif
return kIOReturnSuccess;
}
IOReturn
IOFireWireUserClient::getBusGeneration( UInt32* outGeneration )
{
*outGeneration = getOwner () -> getController () -> getGeneration () ;
return kIOReturnSuccess ;
}
IOReturn
IOFireWireUserClient::getLocalNodeIDWithGeneration( UInt32 testGeneration, UInt32* outLocalNodeID )
{
if ( ! getOwner () -> getController () -> checkGeneration ( testGeneration ) )
return kIOFireWireBusReset ;
*outLocalNodeID = (UInt32) getOwner () -> getController () -> getLocalNodeID () ;
if ( ! getOwner () -> getController () -> checkGeneration ( testGeneration ) )
return kIOFireWireBusReset ;
return kIOReturnSuccess ;
}
IOReturn
IOFireWireUserClient::getRemoteNodeID( UInt32 testGeneration, UInt32* outRemoteNodeID )
{
UInt32 generation ;
UInt16 nodeID ;
IOReturn error = getOwner () -> getNodeIDGeneration ( generation, nodeID ) ;
if (error)
return error ;
if ( generation != testGeneration )
return kIOFireWireBusReset ;
*outRemoteNodeID = (UInt32)nodeID ;
if ( ! getOwner () -> getController () -> checkGeneration ( generation ) )
return kIOFireWireBusReset ;
return error ;
}
IOReturn
IOFireWireUserClient::getSpeedToNode( UInt32 generation, UInt32* outSpeed )
{
if ( ! getOwner () -> getController () -> checkGeneration ( generation ) )
return kIOFireWireBusReset ;
UInt16 nodeID ;
getOwner () -> getNodeIDGeneration( generation, nodeID ) ;
*outSpeed = (UInt32) getOwner () -> getController () -> FWSpeed ( nodeID ) ;
if ( ! getOwner () -> getController () -> checkGeneration ( generation ) )
return kIOFireWireBusReset ;
return kIOReturnSuccess ;
}
IOReturn
IOFireWireUserClient::getSpeedBetweenNodes( UInt32 generation, UInt32 fromNode, UInt32 toNode, UInt32* outSpeed )
{
if ( ! getOwner () -> getController () -> checkGeneration ( generation ) )
return kIOFireWireBusReset ;
*outSpeed = (UInt32)getOwner ()->getController()->FWSpeed( (UInt16)fromNode, (UInt16)toNode ) ;
if (!getOwner ()->getController()->checkGeneration(generation))
return kIOFireWireBusReset ;
return kIOReturnSuccess ;
}
IOReturn
IOFireWireUserClient::getIRMNodeID( UInt32 generation, UInt32* irmNodeID )
{
UInt16 tempNodeID ;
UInt32 tempGeneration ;
IOReturn error = (UInt32)getOwner ()->getController()->getIRMNodeID( tempGeneration, tempNodeID ) ;
if (error)
return error ;
if ( tempGeneration != generation )
return kIOFireWireBusReset ;
*irmNodeID = (UInt32)tempNodeID ;
return kIOReturnSuccess ;
}
IOReturn
IOFireWireUserClient::clipMaxRec2K( Boolean clipMaxRec )
{
if( fClippedMaxRec == clipMaxRec )
return kIOReturnSuccess;
IOReturn error = (UInt32)fOwner->getController()->clipMaxRec2K( clipMaxRec ) ;
if (error)
return error ;
fClippedMaxRec = clipMaxRec;
return kIOReturnSuccess ;
}
IOReturn
IOFireWireUserClient::seize( IOOptionBits inFlags )
{
if ( ! OSDynamicCast(IOFireWireDevice, getOwner ()))
return kIOReturnUnsupported ;
if ( kIOReturnSuccess != clientHasPrivilege( fTask, kIOClientPrivilegeAdministrator ) )
return kIOReturnNotPrivileged ;
if ( getOwner ()->isOpen() )
{
OSIterator* clientIterator = getOwner ()->getOpenClientIterator() ;
if (!clientIterator)
{
DebugLog("IOFireWireUserClient::seize: couldn't make owner client iterator\n") ;
return kIOReturnError ;
}
{
IOService* client = (IOService*)clientIterator->getNextObject() ;
while ( client )
{
if ( client != this )
{
client->message( kIOFWMessageServiceIsRequestingClose, getOwner () ) ;
client->message( kIOMessageServiceIsRequestingClose, getOwner () ) ;
client->terminate() ;
}
client = (IOService*)clientIterator->getNextObject() ;
}
}
clientIterator->release() ;
}
if ( getOwner ()->isOpen() )
{
OSIterator* clientIterator = getOwner ()->getClientIterator() ;
if (!clientIterator)
{
DebugLog("IOFireWireUserClient::seize: couldn't make owner client iterator\n") ;
return kIOReturnError ;
}
{
IOService* client = (IOService*)clientIterator->getNextObject() ;
while ( client )
{
if ( client != this )
{
client->message( kIOFWMessageServiceIsRequestingClose, getOwner () ) ;
client->message( kIOMessageServiceIsRequestingClose, getOwner () ) ;
client->terminate() ;
}
client = (IOService*)clientIterator->getNextObject() ;
}
}
clientIterator->release() ;
}
return kIOReturnSuccess ;
}
IOReturn IOFireWireUserClient::message( UInt32 type, IOService * provider, void * arg )
{
switch(type)
{
case kIOMessageServiceIsSuspended:
if (fBusResetAsyncNotificationRef[0])
sendAsyncResult64(fBusResetAsyncNotificationRef, kIOReturnSuccess, NULL, 0) ;
break ;
case kIOMessageServiceIsResumed:
if (fBusResetDoneAsyncNotificationRef[0])
sendAsyncResult64(fBusResetDoneAsyncNotificationRef, kIOReturnSuccess, NULL, 0) ;
break ;
case kIOFWMessageServiceIsRequestingClose:
getOwner ()->messageClients(kIOMessageServiceIsRequestingClose) ;
break;
}
super::message ( type, provider ) ;
return kIOReturnSuccess;
}
IOReturn
IOFireWireUserClient::getSessionRef( IOFireWireSessionRef * sessionRef )
{
IOReturn error = kIOReturnSuccess;
if( !fOwner->isOpen( this ) )
{
return kIOReturnNotOpen ;
}
*sessionRef = (IOFireWireSessionRef)fSessionRef;
return error ;
}
#pragma mark -
#pragma mark ASYNC STREAM LISTENER
IOReturn
IOFireWireUserClient::setAsyncStreamRef_Packet (
OSAsyncReference64 asyncRef,
UserObjectHandle asyncStreamListenerHandle,
mach_vm_address_t inCallback,
io_user_reference_t inUserRefCon,
void*,
void*,
void*
)
{
IOReturn result = kIOReturnBadArgument;
const OSObject * object = fExporter->lookupObject ( asyncStreamListenerHandle ) ;
if ( !object )
{
return result ;
}
IOFWUserAsyncStreamListener * me = OSDynamicCast ( IOFWUserAsyncStreamListener, object ) ;
if ( ! me )
{
object->release() ;
return result ;
}
if ( inCallback )
super::setAsyncReference64 ( asyncRef, (mach_port_t) asyncRef[0], inCallback, inUserRefCon ) ;
else
asyncRef[0] = 0 ;
me->setAsyncStreamRef_Packet(asyncRef) ;
me->release() ;
return kIOReturnSuccess ;
}
IOReturn
IOFireWireUserClient::setAsyncStreamRef_SkippedPacket (
OSAsyncReference64 asyncRef,
UserObjectHandle inAsyncStreamListenerRef,
mach_vm_address_t inCallback,
io_user_reference_t inUserRefCon,
void*,
void*,
void*)
{
IOReturn result = kIOReturnBadArgument;
const OSObject * object = fExporter->lookupObject ( inAsyncStreamListenerRef ) ;
if ( !object )
{
return result ;
}
result = kIOReturnSuccess ;
IOFWUserAsyncStreamListener * me = OSDynamicCast ( IOFWUserAsyncStreamListener, object ) ;
if ( !me )
{
object->release() ;
result = kIOReturnBadArgument ;
}
if ( kIOReturnSuccess == result )
{
if (inCallback)
super::setAsyncReference64 ( asyncRef, (mach_port_t) asyncRef[0], inCallback, inUserRefCon ) ;
else
asyncRef[0] = 0 ;
me->setAsyncStreamRef_SkippedPacket(asyncRef) ;
}
me->release();
return result ;
}
IOReturn
IOFireWireUserClient::asyncStreamListener_Create (
FWUserAsyncStreamListenerCreateParams* params,
UserObjectHandle* outAsyncStreamListenerHandle )
{
IOFWUserAsyncStreamListener * asyncStreamListener = OSTypeAlloc( IOFWUserAsyncStreamListener );
if ( asyncStreamListener == NULL )
return kIOReturnNoMemory ;
if ( not asyncStreamListener->initAsyncStreamListener( this, params ) )
{
asyncStreamListener->release();
return kIOReturnNoMemory ;
}
IOReturn error = fExporter->addObject ( asyncStreamListener,
(IOFWUserObjectExporter::CleanupFunction)&IOFWUserAsyncStreamListener::exporterCleanup,
outAsyncStreamListenerHandle ) ;
if ( error )
asyncStreamListener->deactivate() ;
asyncStreamListener->release() ;
return error ;
}
IOReturn
IOFireWireUserClient::asyncStreamListener_ClientCommandIsComplete (
UserObjectHandle asyncStreamListenerHandle,
FWClientCommandID inCommandID )
{
const OSObject * object = fExporter->lookupObject( asyncStreamListenerHandle ) ;
if ( !object )
{
return kIOReturnBadArgument ;
}
IOReturn result = kIOReturnSuccess ;
IOFWUserAsyncStreamListener *me = OSDynamicCast( IOFWUserAsyncStreamListener, object ) ;
if (!me)
{
object->release() ;
return kIOReturnBadArgument ;
}
me->clientCommandIsComplete ( inCommandID ) ;
me->release() ;
return result ;
}
IOReturn
IOFireWireUserClient::asyncStreamListener_GetOverrunCounter (
UserObjectHandle asyncStreamListenerHandle,
UInt32 *overrunCounter )
{
IOReturn result = kIOReturnBadArgument ;
const OSObject * object = fExporter->lookupObject( asyncStreamListenerHandle ) ;
if ( !object )
{
return result ;
}
IOFWUserAsyncStreamListener *me = OSDynamicCast( IOFWUserAsyncStreamListener, object ) ;
if ( !me )
{
object->release() ;
return result ;
}
*overrunCounter = me->getOverrunCounter( ) ;
me->release() ;
result = kIOReturnSuccess;
return result ;
}
IOReturn
IOFireWireUserClient::asyncStreamListener_SetFlags (
UserObjectHandle asyncStreamListenerHandle,
UInt32 flags )
{
IOReturn result = kIOReturnBadArgument ;
const OSObject * object = fExporter->lookupObject( asyncStreamListenerHandle ) ;
if ( !object )
{
return result ;
}
IOFWUserAsyncStreamListener *me = OSDynamicCast( IOFWUserAsyncStreamListener, object ) ;
if (!me)
{
object->release() ;
return result;
}
result = kIOReturnSuccess;
me->setFlags( flags ) ;
me->release() ;
return result ;
}
IOReturn
IOFireWireUserClient::asyncStreamListener_GetFlags (
UserObjectHandle asyncStreamListenerHandle,
UInt32 *flags )
{
IOReturn result = kIOReturnBadArgument ;
const OSObject * object = fExporter->lookupObject( asyncStreamListenerHandle ) ;
if ( !object )
{
return result ;
}
IOFWUserAsyncStreamListener *me = OSDynamicCast( IOFWUserAsyncStreamListener, object ) ;
if (!me)
{
object->release() ;
return result ;
}
result = kIOReturnSuccess;
*flags = me->getFlags( ) ;
me->release() ;
return result ;
}
IOReturn
IOFireWireUserClient::asyncStreamListener_TurnOnNotification (
UserObjectHandle asyncStreamListenerHandle )
{
IOReturn result = kIOReturnBadArgument ;
const OSObject * object = fExporter->lookupObject( asyncStreamListenerHandle ) ;
if ( !object )
{
return result ;
}
IOFWUserAsyncStreamListener *me = OSDynamicCast( IOFWUserAsyncStreamListener, object ) ;
if (!me)
{
object->release() ;
return result ;
}
result = kIOReturnSuccess;
me->TurnOnNotification() ;
me->release() ;
return result ;
}
IOReturn
IOFireWireUserClient::asyncStreamListener_TurnOffNotification (
UserObjectHandle asyncStreamListenerHandle )
{
IOReturn result = kIOReturnBadArgument ;
const OSObject * object = fExporter->lookupObject( asyncStreamListenerHandle ) ;
if ( !object )
{
return result ;
}
IOFWUserAsyncStreamListener *me = OSDynamicCast( IOFWUserAsyncStreamListener, object ) ;
if (!me)
{
object->release() ;
return result ;
}
result = kIOReturnSuccess;
me->TurnOffNotification() ;
me->release() ;
return result ;
}
#pragma mark -
#pragma mark IRM ALLOCATIONS
IOReturn
IOFireWireUserClient::allocateIRMBandwidthInGeneration(UInt32 bandwidthUnits, UInt32 generation)
{
return getOwner () -> getController () -> allocateIRMBandwidthInGeneration(bandwidthUnits, generation);
}
IOReturn
IOFireWireUserClient::releaseIRMBandwidthInGeneration(UInt32 bandwidthUnits, UInt32 generation)
{
return getOwner () -> getController () -> releaseIRMBandwidthInGeneration(bandwidthUnits, generation);
}
IOReturn
IOFireWireUserClient::allocateIRMChannelInGeneration(UInt8 isochChannel, UInt32 generation)
{
return getOwner () -> getController () -> allocateIRMChannelInGeneration(isochChannel, generation);
}
IOReturn
IOFireWireUserClient::releaseIRMChannelInGeneration(UInt8 isochChannel, UInt32 generation)
{
return getOwner () -> getController () -> releaseIRMChannelInGeneration(isochChannel, generation);
}
typedef struct UserIRMAllocationParamsStruct
{
io_user_reference_t asyncRef[kOSAsyncRef64Count];
Boolean userNotificationEnabled;
IOFireWireUserClient *pUserClient;
} UserIRMAllocationParams;
static void UserIRMAllocationCleanupFunction( const OSObject * obj )
{
IOFireWireIRMAllocation * pIrmAllocation = (IOFireWireIRMAllocation *) obj;
UserIRMAllocationParams *pUserIRMAllocationParams = (UserIRMAllocationParams*) pIrmAllocation->GetRefCon();
delete pUserIRMAllocationParams;
}
static IOReturn UserIRMAllocationLostNotification(void* refCon, class IOFireWireIRMAllocation* allocation)
{
UserIRMAllocationParams *pUserIRMAllocationParams = (UserIRMAllocationParams*) refCon;
if (pUserIRMAllocationParams->userNotificationEnabled)
pUserIRMAllocationParams->pUserClient->sendAsyncResult64(pUserIRMAllocationParams->asyncRef, kIOReturnSuccess, NULL, 0) ;
return kIOReturnSuccess;
}
IOReturn
IOFireWireUserClient::irmAllocation_Create(Boolean releaseIRMResourcesOnFree, UserObjectHandle* outIRMAllocationHandle)
{
UserIRMAllocationParams *pUserIRMAllocationParams = new UserIRMAllocationParams;
if (!pUserIRMAllocationParams)
return kIOReturnNoMemory ;
else
{
pUserIRMAllocationParams->userNotificationEnabled = false;
pUserIRMAllocationParams->pUserClient = this;
}
IOFireWireIRMAllocation * irmAllocation = OSTypeAlloc( IOFireWireIRMAllocation );
if (!irmAllocation)
{
delete pUserIRMAllocationParams;
return kIOReturnNoMemory ;
}
if (!irmAllocation->init(getOwner()->getController(), releaseIRMResourcesOnFree, UserIRMAllocationLostNotification, pUserIRMAllocationParams))
{
irmAllocation->release();
delete pUserIRMAllocationParams;
return kIOReturnNoMemory ;
}
IOReturn error = fExporter->addObject ( irmAllocation, UserIRMAllocationCleanupFunction, outIRMAllocationHandle ) ;
irmAllocation->release() ;
return error ;
}
IOReturn
IOFireWireUserClient::irmAllocation_AllocateResources(UserObjectHandle irmAllocationHandle, UInt8 isochChannel, UInt32 bandwidthUnits)
{
IOReturn result = kIOReturnBadArgument ;
const OSObject * object = fExporter->lookupObject( irmAllocationHandle ) ;
if ( !object )
{
return result ;
}
IOFireWireIRMAllocation *me = OSDynamicCast( IOFireWireIRMAllocation, object ) ;
if (!me)
{
object->release() ;
return result ;
}
result = me->allocateIsochResources(isochChannel, bandwidthUnits) ;
me->release() ;
return result ;
}
IOReturn
IOFireWireUserClient::irmAllocation_DeallocateResources(UserObjectHandle irmAllocationHandle)
{
IOReturn result = kIOReturnBadArgument ;
const OSObject * object = fExporter->lookupObject( irmAllocationHandle ) ;
if ( !object )
{
return result ;
}
IOFireWireIRMAllocation *me = OSDynamicCast( IOFireWireIRMAllocation, object ) ;
if (!me)
{
object->release() ;
return result ;
}
result = me->deallocateIsochResources();
me->release() ;
return result ;
}
Boolean
IOFireWireUserClient::irmAllocation_areResourcesAllocated(UserObjectHandle irmAllocationHandle, UInt8 *pIsochChannel, UInt32 *pBandwidthUnits)
{
Boolean result = false ;
const OSObject * object = fExporter->lookupObject( irmAllocationHandle ) ;
if ( !object )
{
return false ;
}
IOFireWireIRMAllocation *me = OSDynamicCast( IOFireWireIRMAllocation, object ) ;
if (!me)
{
object->release() ;
return false ;
}
result = me->areIsochResourcesAllocated(pIsochChannel, pBandwidthUnits);
me->release() ;
return result ;
}
void
IOFireWireUserClient::irmAllocation_setDeallocateOnRelease(UserObjectHandle irmAllocationHandle, Boolean doDeallocationOnRelease)
{
const OSObject * object = fExporter->lookupObject( irmAllocationHandle ) ;
if ( !object )
{
return;
}
IOFireWireIRMAllocation *me = OSDynamicCast( IOFireWireIRMAllocation, object ) ;
if (!me)
{
object->release() ;
return;
}
me->setReleaseIRMResourcesOnFree(doDeallocationOnRelease);
me->release() ;
return;
}
IOReturn
IOFireWireUserClient::irmAllocation_setRef(OSAsyncReference64 asyncRef,
UserObjectHandle irmAllocationHandle,
io_user_reference_t inCallback,
io_user_reference_t inUserRefCon)
{
IOReturn result = kIOReturnBadArgument ;
const OSObject * object = fExporter->lookupObject( irmAllocationHandle ) ;
if ( !object )
{
return result ;
}
IOFireWireIRMAllocation *me = OSDynamicCast( IOFireWireIRMAllocation, object ) ;
if (!me)
{
object->release() ;
return result ;
}
UserIRMAllocationParams *pUserIRMAllocationParams = (UserIRMAllocationParams*) me->GetRefCon();
for (UInt32 i=0;i<kOSAsyncRef64Count;i++)
pUserIRMAllocationParams->asyncRef[i] = asyncRef[i];
pUserIRMAllocationParams->asyncRef[ kIOAsyncCalloutFuncIndex ] = (mach_vm_address_t)inCallback ;
pUserIRMAllocationParams->asyncRef[ kIOAsyncCalloutRefconIndex ] = inUserRefCon ;
if (inCallback)
pUserIRMAllocationParams->userNotificationEnabled = true;
else
pUserIRMAllocationParams->userNotificationEnabled = false;
me->release() ;
return result ;
}
IOReturn
IOFireWireUserClient::createVectorCommand( UserObjectHandle * kernel_ref )
{
IOReturn status = kIOReturnSuccess;
IOFWUserVectorCommand * cmd = NULL;
if( status == kIOReturnSuccess )
{
cmd = IOFWUserVectorCommand::withUserClient( this );
if( !cmd )
status = kIOReturnNoMemory;
}
if( status == kIOReturnSuccess )
{
status = fExporter->addObject( cmd, NULL, kernel_ref );
}
if( cmd )
{
cmd->release(); cmd = NULL;
}
return status;
}
IOReturn
IOFireWireUserClient::createPHYPacketListener( UInt32 queue_count, UserObjectHandle * kernel_ref )
{
IOReturn status = kIOReturnSuccess;
IOFWUserPHYPacketListener * listener = NULL;
if( status == kIOReturnSuccess )
{
listener = IOFWUserPHYPacketListener::withUserClient( this, queue_count );
if( !listener )
status = kIOReturnNoMemory;
}
if( status == kIOReturnSuccess )
{
status = fExporter->addObject( listener, (IOFWUserObjectExporter::CleanupFunction)&IOFWUserPHYPacketListener::exporterCleanup, kernel_ref );
}
if( listener )
{
listener->release(); listener = NULL;
}
return status;
}