IOFireWireSBP2LibORB.cpp [plain text]
#include <CoreFoundation/CoreFoundation.h>
#include "FWDebugging.h"
#include "IOFireWireSBP2LibORB.h"
#include <System/libkern/OSCrossEndian.h>
__BEGIN_DECLS
#include <IOKit/iokitmig.h>
#include <mach/mach.h>
__END_DECLS
IOFireWireSBP2LibORBInterface IOFireWireSBP2LibORB::sIOFireWireSBP2LibORBInterface =
{
0,
&IOFireWireSBP2LibORB::staticQueryInterface,
&IOFireWireSBP2LibORB::staticAddRef,
&IOFireWireSBP2LibORB::staticRelease,
1, 0, &IOFireWireSBP2LibORB::staticSetRefCon,
&IOFireWireSBP2LibORB::staticGetRefCon,
&IOFireWireSBP2LibORB::staticSetCommandFlags,
&IOFireWireSBP2LibORB::staticSetMaxORBPayloadSize,
&IOFireWireSBP2LibORB::staticSetCommandTimeout,
&IOFireWireSBP2LibORB::staticSetCommandGeneration,
&IOFireWireSBP2LibORB::staticSetCommandBuffersAsRanges,
&IOFireWireSBP2LibORB::staticReleaseCommandBuffers,
&IOFireWireSBP2LibORB::staticSetCommandBlock,
&IOFireWireSBP2LibORB::staticLSIWorkaroundSetCommandBuffersAsRanges,
&IOFireWireSBP2LibORB::staticLSIWorkaroundSyncBuffersForOutput,
&IOFireWireSBP2LibORB::staticLSIWorkaroundSyncBuffersForInput
};
IUnknownVTbl ** IOFireWireSBP2LibORB::alloc( io_connect_t connection,
mach_port_t asyncPort )
{
IOReturn status = kIOReturnSuccess;
IOFireWireSBP2LibORB * me;
IUnknownVTbl ** interface = NULL;
if( status == kIOReturnSuccess )
{
me = new IOFireWireSBP2LibORB();
if( me == NULL )
status = kIOReturnError;
}
if( status == kIOReturnSuccess )
{
status = me->init( connection, asyncPort );
}
if( status != kIOReturnSuccess )
delete me;
if( status == kIOReturnSuccess )
{
me->addRef();
interface = (IUnknownVTbl **) &me->fIOFireWireSBP2LibORBInterface.pseudoVTable;
}
return interface;
}
IOFireWireSBP2LibORB::IOFireWireSBP2LibORB( void )
{
fRefCount = 0;
fConnection = 0;
fORBRef = 0;
fRefCon = 0;
fRangeScratch = NULL;
fRangeScratchLength = 0;
fIOFireWireSBP2LibORBInterface.pseudoVTable
= (IUnknownVTbl *) &sIOFireWireSBP2LibORBInterface;
fIOFireWireSBP2LibORBInterface.obj = this;
}
IOReturn IOFireWireSBP2LibORB::init( io_connect_t connection, mach_port_t asyncPort )
{
IOReturn status = kIOReturnSuccess;
fConnection = connection;
fAsyncPort = asyncPort;
FWLOG(( "IOFireWireSBP2LibORB : fConnection %d, fAsyncPort %d\n",
fConnection, fAsyncPort ));
if( !fConnection || !fAsyncPort )
status = kIOReturnError;
if( status == kIOReturnSuccess )
{
uint32_t len = 1;
status = IOConnectCallScalarMethod( connection, kIOFWSBP2UserClientCreateORB,
NULL, 0, &fORBRef, &len );
if( status != kIOReturnSuccess )
fORBRef = 0;
FWLOG(( "IOFireWireSBP2LibORB : status = 0x%08x = fORBRef 0x%08lx\n",
status, fORBRef ));
}
return status;
}
IOFireWireSBP2LibORB::~IOFireWireSBP2LibORB()
{
if( fORBRef )
{
IOReturn status = kIOReturnSuccess;
uint32_t len = 0;
status = IOConnectCallScalarMethod( fConnection,
kIOFWSBP2UserClientReleaseORB,
&fORBRef, 1, NULL, &len );
FWLOG(( "IOFireWireSBP2LibORB : release orb status = 0x%08x\n", status ));
}
}
HRESULT IOFireWireSBP2LibORB::staticQueryInterface( void * self, REFIID iid, void **ppv )
{
return getThis(self)->queryInterface( iid, ppv );
}
HRESULT IOFireWireSBP2LibORB::queryInterface( REFIID iid, void **ppv )
{
CFUUIDRef uuid = CFUUIDCreateFromUUIDBytes(NULL, iid);
HRESULT result = S_OK;
if( CFEqual(uuid, IUnknownUUID) || CFEqual(uuid, kIOFireWireSBP2LibORBInterfaceID) )
{
*ppv = &fIOFireWireSBP2LibORBInterface;
addRef();
}
else
*ppv = 0;
if( !*ppv )
result = E_NOINTERFACE;
CFRelease( uuid );
return result;
}
UInt32 IOFireWireSBP2LibORB::staticAddRef( void * self )
{
return getThis(self)->addRef();
}
UInt32 IOFireWireSBP2LibORB::addRef()
{
fRefCount += 1;
return fRefCount;
}
UInt32 IOFireWireSBP2LibORB::staticRelease( void * self )
{
return getThis(self)->release();
}
UInt32 IOFireWireSBP2LibORB::release( void )
{
UInt32 retVal = fRefCount;
if( 1 == fRefCount-- )
{
if( fRangeScratch != NULL )
{
vm_deallocate( mach_task_self(), (vm_address_t)fRangeScratch, fRangeScratchLength );
fRangeScratch = NULL;
fRangeScratchLength = 0;
}
delete this;
}
return retVal;
}
void IOFireWireSBP2LibORB::staticSetRefCon( void * self, void * refCon )
{
getThis(self)->setRefCon( refCon );
}
void IOFireWireSBP2LibORB::setRefCon( void * refCon )
{
FWLOG(( "IOFireWireSBP2LibORB : setRefCon\n"));
fRefCon = refCon;
uint32_t len = 0;
uint64_t params[2];
params[0] = fORBRef;
params[1] = (uint64_t)refCon;
IOConnectCallScalarMethod( fConnection,
kIOFWSBP2UserClientSetORBRefCon,
params, 2, NULL, &len );
}
void * IOFireWireSBP2LibORB::staticGetRefCon( void * self )
{
return getThis(self)->getRefCon();
}
void * IOFireWireSBP2LibORB::getRefCon( void )
{
return fRefCon;
}
void IOFireWireSBP2LibORB::staticSetCommandFlags( void * self, UInt32 flags )
{
getThis(self)->setCommandFlags( flags );
}
void IOFireWireSBP2LibORB::setCommandFlags( UInt32 flags )
{
FWLOG(( "IOFireWireSBP2LibORB : setCommandFlags = %ld\n", flags ));
uint32_t len = 0;
uint64_t params[2];
params[0] = fORBRef;
params[1] = flags;
IOConnectCallScalarMethod( fConnection,
kIOFWSBP2UserClientSetCommandFlags,
params, 2, NULL, &len );
}
void IOFireWireSBP2LibORB::staticSetMaxORBPayloadSize( void * self, UInt32 size )
{
getThis(self)->setMaxORBPayloadSize( size );
}
void IOFireWireSBP2LibORB::setMaxORBPayloadSize( UInt32 size )
{
FWLOG(( "IOFireWireSBP2LibORB : setMaxORBPayloadSize = %ld\n", size ));
uint32_t len = 0;
uint64_t params[2];
params[0] = fORBRef;
params[1] = size;
IOConnectCallScalarMethod( fConnection,
kIOFWSBP2UserClientSetMaxORBPayloadSize,
params, 2, NULL, &len );
}
void IOFireWireSBP2LibORB::staticSetCommandTimeout( void * self, UInt32 timeout )
{
getThis(self)->setCommandTimeout( timeout );
}
void IOFireWireSBP2LibORB::setCommandTimeout( UInt32 timeout )
{
FWLOG(( "IOFireWireSBP2LibORB : setCommandTimeout = %ld\n", timeout ));
uint32_t len = 0;
uint64_t params[2];
params[0] = fORBRef;
params[1] = timeout;
IOConnectCallScalarMethod( fConnection,
kIOFWSBP2UserClientSetCommandTimeout,
params, 2, NULL, &len );
}
void IOFireWireSBP2LibORB::staticSetCommandGeneration( void * self, UInt32 generation )
{
getThis(self)->setCommandGeneration( generation );
}
void IOFireWireSBP2LibORB::setCommandGeneration( UInt32 generation )
{
FWLOG(( "IOFireWireSBP2LibORB : setCommandGeneration = %ld\n", generation ));
uint32_t len = 0;
uint64_t params[2];
params[0] = fORBRef;
params[1] = generation;
IOConnectCallScalarMethod( fConnection,
kIOFWSBP2UserClientSetCommandGeneration,
params, 2, NULL, &len );
}
void IOFireWireSBP2LibORB::staticSetToDummy( void * self )
{
getThis(self)->setToDummy();
}
void IOFireWireSBP2LibORB::setToDummy( void )
{
IOReturn status = kIOReturnSuccess;
FWLOG(( "IOFireWireSBP2LibORB : setToDummy\n" ));
uint32_t len = 0;
status = IOConnectCallScalarMethod( fConnection,
kIOFWSBP2UserClientSetToDummy,
&fORBRef, 1, NULL, &len );
}
IOReturn IOFireWireSBP2LibORB::staticSetCommandBuffersAsRanges( void * self,
FWSBP2VirtualRange * ranges, UInt32 withCount,
UInt32 withDirection,
UInt32 offset, UInt32 length )
{
return getThis(self)->setCommandBuffersAsRanges( ranges, withCount, withDirection,
offset, length);
}
IOReturn IOFireWireSBP2LibORB::setCommandBuffersAsRanges( FWSBP2VirtualRange * ranges,
UInt32 withCount, UInt32 withDirection,
UInt32 offset,
UInt32 length )
{
IOReturn status = kIOReturnSuccess;
uint32_t len = 0;
uint64_t params[6];
FWLOG(( "IOFireWireSBP2LibORB : setCommandBuffersAsRanges\n" ));
UInt32 range_length = withCount * sizeof(FWSBP2PrivateVirtualRange);
if( fRangeScratchLength < range_length )
{
if( fRangeScratch != NULL )
{
vm_deallocate( mach_task_self(), (vm_address_t)fRangeScratch, fRangeScratchLength );
fRangeScratch = NULL;
fRangeScratchLength = 0;
}
vm_allocate( mach_task_self(), (vm_address_t*)&fRangeScratch, range_length, true );
if( fRangeScratch != NULL )
{
fRangeScratchLength = range_length;
}
}
if( fRangeScratch != NULL )
{
for( UInt32 i = 0; i < withCount; i++ )
{
fRangeScratch[i].address = (uint64_t)ranges[i].address;
fRangeScratch[i].length = ranges[i].length;
ROSETTA_ONLY(
fRangeScratch[i].address = OSSwapInt64( fRangeScratch[i].address );
fRangeScratch[i].length = OSSwapInt64( fRangeScratch[i].length );
);
}
}
params[0] = fORBRef;
params[1] = (uint64_t)fRangeScratch;
params[2] = withCount;
params[3] = withDirection;
params[4] = offset;
params[5] = length;
status = IOConnectCallScalarMethod( fConnection,
kIOFWSBP2UserClientSetCommandBuffersAsRanges,
params, 6, NULL, &len );
return status;
}
IOReturn IOFireWireSBP2LibORB::staticReleaseCommandBuffers( void * self )
{
return getThis(self)->releaseCommandBuffers();
}
IOReturn IOFireWireSBP2LibORB::releaseCommandBuffers( void )
{
IOReturn status = kIOReturnSuccess;
FWLOG(( "IOFireWireSBP2LibORB : releaseCommandBuffers\n" ));
uint32_t len = 0;
status = IOConnectCallScalarMethod( fConnection,
kIOFWSBP2UserClientReleaseCommandBuffers,
&fORBRef, 1, NULL, &len );
return status;
}
IOReturn IOFireWireSBP2LibORB::staticSetCommandBlock( void * self, void * buffer,
UInt32 length )
{
return getThis(self)->setCommandBlock( buffer, length );
}
IOReturn IOFireWireSBP2LibORB::setCommandBlock( void * buffer, UInt32 length )
{
IOReturn status = kIOReturnSuccess;
FWLOG(( "IOFireWireSBP2LibORB : setCommandBlock\n" ));
uint32_t len = 0;
uint64_t params[3];
vm_address_t address = 0;
status = vm_allocate( mach_task_self(), &address, length, true );
if( address == 0 )
{
status = kIOReturnNoMemory;
}
if( status == kIOReturnSuccess )
{
bcopy( buffer, (void*)address, length );
params[0] = fORBRef;
params[1] = address;
params[2] = length;
status = IOConnectCallScalarMethod( fConnection,
kIOFWSBP2UserClientSetCommandBlock,
params, 3, NULL, &len );
}
if( address )
{
vm_deallocate( mach_task_self(), address, length );
}
return status;
}
IOReturn IOFireWireSBP2LibORB::staticLSIWorkaroundSetCommandBuffersAsRanges
( void * self, FWSBP2VirtualRange * ranges, UInt32 withCount,
UInt32 withDirection, UInt32 offset, UInt32 length )
{
return getThis( self )->LSIWorkaroundSetCommandBuffersAsRanges( ranges, withCount, withDirection,
offset, length );
}
IOReturn IOFireWireSBP2LibORB::LSIWorkaroundSetCommandBuffersAsRanges
( FWSBP2VirtualRange * ranges, UInt32 withCount,
UInt32 withDirection, UInt32 offset, UInt32 length )
{
IOReturn status = kIOReturnSuccess;
uint32_t len = 0;
uint64_t params[6];
FWLOG(( "IOFireWireSBP2LibORB : setCommandBuffersAsRanges\n" ));
UInt32 range_length = withCount * sizeof(FWSBP2PrivateVirtualRange);
if( fRangeScratchLength < range_length )
{
if( fRangeScratch != NULL )
{
vm_deallocate( mach_task_self(), (vm_address_t)fRangeScratch, fRangeScratchLength );
fRangeScratch = NULL;
fRangeScratchLength = 0;
}
vm_allocate( mach_task_self(), (vm_address_t*)&fRangeScratch, range_length, true );
if( fRangeScratch != NULL )
{
fRangeScratchLength = range_length;
}
}
if( fRangeScratch != NULL )
{
for( UInt32 i = 0; i < withCount; i++ )
{
fRangeScratch[i].address = (uint64_t)ranges[i].address;
fRangeScratch[i].length = ranges[i].length;
ROSETTA_ONLY(
fRangeScratch[i].address = OSSwapInt64( fRangeScratch[i].address );
fRangeScratch[i].length = OSSwapInt64( fRangeScratch[i].length );
);
}
}
params[0] = fORBRef;
params[1] = (uint64_t)fRangeScratch;
params[2] = withCount;
params[3] = withDirection;
params[4] = offset;
params[5] = length;
status = IOConnectCallScalarMethod( fConnection,
kIOFWSBP2UserClientLSIWorkaroundSetCommandBuffersAsRanges,
params, 6, NULL, &len );
return status;
}
IOReturn IOFireWireSBP2LibORB::staticLSIWorkaroundSyncBuffersForOutput( void * self )
{
return getThis( self )->LSIWorkaroundSyncBuffersForOutput();
}
IOReturn IOFireWireSBP2LibORB::LSIWorkaroundSyncBuffersForOutput( void )
{
IOReturn status = kIOReturnSuccess;
FWLOG(( "IOFireWireSBP2LibORB : LSIWorkaroundSyncBuffersForOutput\n" ));
uint32_t len = 0;
status = IOConnectCallScalarMethod( fConnection,
kIOFWSBP2UserClientMgmtORBLSIWorkaroundSyncBuffersForOutput,
&fORBRef, 1, NULL, &len );
return status;
}
IOReturn IOFireWireSBP2LibORB::staticLSIWorkaroundSyncBuffersForInput( void * self )
{
return getThis( self )->LSIWorkaroundSyncBuffersForInput();
}
IOReturn IOFireWireSBP2LibORB::LSIWorkaroundSyncBuffersForInput( void )
{
IOReturn status = kIOReturnSuccess;
FWLOG(( "IOFireWireSBP2LibORB : LSIWorkaroundSyncBuffersForInput\n" ));
uint32_t len = 0;
status = IOConnectCallScalarMethod( fConnection,
kIOFWSBP2UserClientMgmtORBLSIWorkaroundSyncBuffersForInput,
&fORBRef, 1, NULL, &len );
return status;
}
UInt32 IOFireWireSBP2LibORB::getORBRef( void )
{
return fORBRef;
}