IOFireWireLibPsudoAddrSpace.cpp [plain text]
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/iokitmig.h>
#include "IOFireWireLibPriv.h"
#include "IOFireWireLibPsudoAddrSpace.h"
IOFireWirePseudoAddressSpaceInterface IOFireWirePseudoAddressSpaceImp::sInterface =
{
INTERFACEIMP_INTERFACE,
1, 0, & IOFireWirePseudoAddressSpaceImp::SSetWriteHandler,
& IOFireWirePseudoAddressSpaceImp::SSetReadHandler,
& IOFireWirePseudoAddressSpaceImp::SSetSkippedPacketHandler,
& IOFireWirePseudoAddressSpaceImp::SNotificationIsOn,
& IOFireWirePseudoAddressSpaceImp::STurnOnNotification,
& IOFireWirePseudoAddressSpaceImp::STurnOffNotification,
& IOFireWirePseudoAddressSpaceImp::SClientCommandIsComplete,
& IOFireWirePseudoAddressSpaceImp::SGetFWAddress,
& IOFireWirePseudoAddressSpaceImp::SGetBuffer,
& IOFireWirePseudoAddressSpaceImp::SGetBufferSize,
& IOFireWirePseudoAddressSpaceImp::SGetRefCon
} ;
IUnknownVTbl**
IOFireWirePseudoAddressSpaceImp::Alloc(
IOFireWireDeviceInterfaceImp& inUserClient,
FWKernAddrSpaceRef inKernAddrSpaceRef,
void* inBuffer,
UInt32 inBufferSize,
void* inBackingStore,
void* inRefCon)
{
IOFireWirePseudoAddressSpaceImp * me;
IUnknownVTbl** interface = NULL;
me = new IOFireWirePseudoAddressSpaceImp(inUserClient, inKernAddrSpaceRef, inBuffer, inBufferSize, inBackingStore, inRefCon) ;
if( me && (kIOReturnSuccess == me->Init()) )
{
interface = & me->mInterface.pseudoVTable;
}
else
delete me ;
return interface;
}
HRESULT STDMETHODCALLTYPE
IOFireWirePseudoAddressSpaceImp::QueryInterface(REFIID iid, LPVOID* ppv)
{
HRESULT result = S_OK ;
*ppv = nil ;
CFUUIDRef interfaceID = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault, iid) ;
if ( CFEqual(interfaceID, IUnknownUUID) || CFEqual(interfaceID, kIOFireWirePseudoAddressSpaceInterfaceID) )
{
*ppv = & mInterface ;
AddRef() ;
}
else
{
*ppv = nil ;
result = E_NOINTERFACE ;
}
CFRelease(interfaceID) ;
return result ;
}
const IOFireWirePseudoAddressSpaceWriteHandler
IOFireWirePseudoAddressSpaceImp::SSetWriteHandler(IOFireWireLibPseudoAddressSpaceRef self, IOFireWirePseudoAddressSpaceWriteHandler inWriter)
{
return GetThis(self)->SetWriteHandler(inWriter);
}
const IOFireWirePseudoAddressSpaceReadHandler
IOFireWirePseudoAddressSpaceImp::SSetReadHandler(IOFireWireLibPseudoAddressSpaceRef self, IOFireWirePseudoAddressSpaceReadHandler inReader)
{
return GetThis(self)->SetReadHandler(inReader);
}
const IOFireWirePseudoAddressSpaceSkippedPacketHandler
IOFireWirePseudoAddressSpaceImp::SSetSkippedPacketHandler(IOFireWireLibPseudoAddressSpaceRef self, IOFireWirePseudoAddressSpaceSkippedPacketHandler inHandler)
{
return GetThis(self)->SetSkippedPacketHandler(inHandler);
}
Boolean
IOFireWirePseudoAddressSpaceImp::SNotificationIsOn(IOFireWireLibPseudoAddressSpaceRef self)
{
return GetThis(self)->mNotifyIsOn;
}
Boolean
IOFireWirePseudoAddressSpaceImp::STurnOnNotification(IOFireWireLibPseudoAddressSpaceRef self)
{
return GetThis(self)->TurnOnNotification(self);
}
void
IOFireWirePseudoAddressSpaceImp::STurnOffNotification(IOFireWireLibPseudoAddressSpaceRef self)
{
GetThis(self)->TurnOffNotification();
}
void
IOFireWirePseudoAddressSpaceImp::SClientCommandIsComplete(IOFireWireLibPseudoAddressSpaceRef self, FWClientCommandID commandID, IOReturn status)
{
GetThis(self)->ClientCommandIsComplete(commandID, status);
}
void
IOFireWirePseudoAddressSpaceImp::SGetFWAddress(IOFireWireLibPseudoAddressSpaceRef self, FWAddress* outAddr)
{
bcopy (&GetThis(self)->mFWAddress, outAddr, sizeof(FWAddress));
}
void*
IOFireWirePseudoAddressSpaceImp::SGetBuffer(IOFireWireLibPseudoAddressSpaceRef self)
{
return GetThis(self)->mBuffer;
}
const UInt32
IOFireWirePseudoAddressSpaceImp::SGetBufferSize(IOFireWireLibPseudoAddressSpaceRef self)
{
return GetThis(self)->mBufferSize;
}
void*
IOFireWirePseudoAddressSpaceImp::SGetRefCon(IOFireWireLibPseudoAddressSpaceRef self)
{
return GetThis(self)->mRefCon;
}
#pragma mark -
IOFireWirePseudoAddressSpaceImp::IOFireWirePseudoAddressSpaceImp(
IOFireWireDeviceInterfaceImp& inUserClient,
FWKernAddrSpaceRef inKernAddrSpaceRef,
void* inBuffer,
UInt32 inBufferSize,
void* inBackingStore,
void* inRefCon) : IOFireWireIUnknown(), mNotifyIsOn(false),
mUserClient(inUserClient),
mKernAddrSpaceRef(inKernAddrSpaceRef),
mBuffer(inBuffer),
mBufferSize(inBufferSize),
mBackingStore(inBackingStore),
mRefCon(inRefCon)
{
inUserClient.AddRef() ;
mInterface.pseudoVTable = (IUnknownVTbl*) & sInterface ;
mInterface.obj = this ;
}
IOFireWirePseudoAddressSpaceImp::~IOFireWirePseudoAddressSpaceImp()
{
IOReturn result = IOConnectMethodScalarIScalarO( mUserClient.GetUserClientConnection(),
kFWPseudoAddrSpace_Release,
1,
0,
mKernAddrSpaceRef) ;
if (kIOReturnSuccess != result)
fprintf(stderr, "IOFireWirePseudoAddressSpaceImp::~IOFireWirePseudoAddressSpaceImp: error releasing address space!\n") ;
mUserClient.Release() ;
}
IOReturn
IOFireWirePseudoAddressSpaceImp::Init()
{
IOReturn err = kIOReturnSuccess ;
io_scalar_inband_t params = {(int)mKernAddrSpaceRef} ;
io_scalar_inband_t output;
mach_msg_type_number_t size = 3 ;
err = io_connect_method_scalarI_scalarO(
mUserClient.GetUserClientConnection(),
kFWPseudoAddrSpace_GetFWAddrInfo,
params,
1,
output,
& size) ;
#if __IOFireWireClientDebug__
fprintf(stderr, "IOFireWirePseudoAddressSpaceImp::Init(): kr = %08lX\n",(UInt32) err) ;
#endif
if ( kIOReturnSuccess == err )
{
mFWAddress = FWAddress(output[1], output[2], output[0]) ;
}
#if __IOFireWireClientDebug__
fprintf(stderr, "mFWAddress = %04lX:%08lX\n", (UInt16) mFWAddress.addressHi, (UInt32) mFWAddress.addressLo) ;
#endif
return err ;
}
#pragma mark -
#pragma mark --callback management
const IOFireWirePseudoAddressSpaceWriteHandler
IOFireWirePseudoAddressSpaceImp::SetWriteHandler(
IOFireWirePseudoAddressSpaceWriteHandler inWriter)
{
IOFireWirePseudoAddressSpaceWriteHandler oldWriter = mWriter ;
mWriter = inWriter ;
return oldWriter ;
}
const IOFireWirePseudoAddressSpaceReadHandler
IOFireWirePseudoAddressSpaceImp::SetReadHandler(
IOFireWirePseudoAddressSpaceReadHandler inReader)
{
IOFireWirePseudoAddressSpaceReadHandler oldReader = mReader ;
mReader = inReader ;
return oldReader ;
}
const IOFireWirePseudoAddressSpaceSkippedPacketHandler
IOFireWirePseudoAddressSpaceImp::SetSkippedPacketHandler(
IOFireWirePseudoAddressSpaceSkippedPacketHandler inHandler)
{
IOFireWirePseudoAddressSpaceSkippedPacketHandler result = mSkippedPacketHandler ;
mSkippedPacketHandler = inHandler ;
return result ;
}
Boolean
IOFireWirePseudoAddressSpaceImp::TurnOnNotification(
void* callBackRefCon)
{
IOReturn err = kIOReturnSuccess ;
io_connect_t connection = mUserClient.GetUserClientConnection() ;
io_scalar_inband_t params ;
io_scalar_inband_t output ;
mach_msg_type_number_t size = 0 ;
if (mNotifyIsOn)
return kIOReturnSuccess ;
if (!connection)
err = kIOReturnNoDevice ;
if ( kIOReturnSuccess == err )
{
params[0] = (UInt32)mKernAddrSpaceRef ;
params[1] = (UInt32)(IOAsyncCallback) & IOFireWirePseudoAddressSpaceImp::Writer ;
params[2] = (UInt32) callBackRefCon;
err = io_async_method_scalarI_scalarO(
connection,
mUserClient.GetAsyncPort(),
mPacketAsyncRef,
1,
kFWSetAsyncRef_Packet,
params,
3,
output,
& size) ;
}
if ( kIOReturnSuccess == err)
{
size=0 ;
params[0] = (UInt32) mKernAddrSpaceRef ;
params[1] = (UInt32)(IOAsyncCallback2) & IOFireWirePseudoAddressSpaceImp::SkippedPacketHandler ;
params[2] = (UInt32) callBackRefCon;
err = io_async_method_scalarI_scalarO(
connection,
mUserClient.GetAsyncPort(),
mSkippedPacketAsyncRef,
1,
kFWSetAsyncRef_SkippedPacket,
params,
3,
output,
& size) ;
}
if ( kIOReturnSuccess == err)
{
params[0] = (UInt32) mKernAddrSpaceRef ;
params[1] = (UInt32) & IOFireWirePseudoAddressSpaceImp::ReadHandler ;
params[2] = (UInt32) this ;
err = io_async_method_scalarI_scalarO(
connection,
mUserClient.GetAsyncPort(),
mSkippedPacketAsyncRef,
1,
kFWSetAsyncRef_Read,
params,
3,
params,
& size) ;
}
if ( kIOReturnSuccess == err )
mNotifyIsOn = true ;
return ( kIOReturnSuccess == err ) ;
}
void
IOFireWirePseudoAddressSpaceImp::TurnOffNotification()
{
IOReturn err = kIOReturnSuccess ;
io_connect_t connection = mUserClient.GetUserClientConnection() ;
io_scalar_inband_t params ;
mach_msg_type_number_t size = 0 ;
if (!mNotifyIsOn)
return ;
if (!connection)
err = kIOReturnNoDevice ;
if ( kIOReturnSuccess == err )
{
params[0] = (UInt32) mKernAddrSpaceRef ;
params[1] = (UInt32)(IOAsyncCallback) 0 ;
params[2] = (UInt32) this ;
err = io_async_method_scalarI_scalarO(
connection,
mUserClient.GetAsyncPort(),
mPacketAsyncRef,
1,
kFWSetAsyncRef_Packet,
params,
3,
params,
& size) ;
params[0] = (UInt32) mKernAddrSpaceRef ;
params[1] = (UInt32)(IOAsyncCallback) 0 ;
params[2] = (UInt32) this ;
err = io_async_method_scalarI_scalarO(
connection,
mUserClient.GetAsyncPort(),
mSkippedPacketAsyncRef,
1,
kFWSetAsyncRef_SkippedPacket,
params,
3,
params,
& size) ;
}
mNotifyIsOn = false ;
}
void
IOFireWirePseudoAddressSpaceImp::ClientCommandIsComplete(
FWClientCommandID commandID,
IOReturn status)
{
io_scalar_inband_t params = {(int)mKernAddrSpaceRef, (int)commandID} ;
mach_msg_type_number_t size = 0 ;
OSStatus err = io_connect_method_scalarI_scalarO(
mUserClient.GetUserClientConnection(),
kFWPseudoAddrSpace_ClientCommandIsComplete,
params,
2,
params,
& size) ;
assert( kIOReturnSuccess == err ) ;
}
void
IOFireWirePseudoAddressSpaceImp::Writer(
IOFireWireLibPseudoAddressSpaceRef refCon,
IOReturn result,
void** args,
int numArgs)
{
IOFireWirePseudoAddressSpaceImp* me = GetThis(refCon);
if (me->mWriter)
(me->mWriter)(
(IOFireWireLibPseudoAddressSpaceRef) refCon,
(FWClientCommandID) args[0], (UInt32) args[1], (char*)me->mBuffer + (UInt32)args[2], (UInt16) args[3], (UInt32)args[5], (UInt32)args[6],
(UInt32) me->mRefCon) ; }
void
IOFireWirePseudoAddressSpaceImp::SkippedPacketHandler(
IOFireWireLibPseudoAddressSpaceRef refCon,
IOReturn result,
FWClientCommandID commandID,
UInt32 packetCount)
{
IOFireWirePseudoAddressSpaceImp* me = GetThis(refCon) ;
if (me->mSkippedPacketHandler)
(me->mSkippedPacketHandler)(
(IOFireWireLibPseudoAddressSpaceRef) refCon,
commandID,
packetCount) ;
}
#pragma mark -
#pragma mark --accessors
const FWAddress&
IOFireWirePseudoAddressSpaceImp::GetFWAddress()
{
return mFWAddress ;
}
void*
IOFireWirePseudoAddressSpaceImp::GetBuffer()
{
return mBuffer ;
}
const UInt32
IOFireWirePseudoAddressSpaceImp::GetBufferSize()
{
return mBufferSize ;
}
void*
IOFireWirePseudoAddressSpaceImp::GetRefCon()
{
return mRefCon ;
}