IOFWPseudoAddressSpace.cpp [plain text]
#include <IOKit/firewire/IOFWAddressSpace.h>
#include <IOKit/firewire/IOFireWireController.h>
#include "FWDebugging.h"
OSData *IOFWPseudoAddressSpace::allocatedAddresses = NULL;
OSDefineMetaClassAndStructors(IOFWPseudoAddressSpaceAux, IOFWAddressSpaceAux);
OSMetaClassDefineReservedUsed(IOFWPseudoAddressSpaceAux, 0);
OSMetaClassDefineReservedUsed(IOFWPseudoAddressSpaceAux, 1);
OSMetaClassDefineReservedUnused(IOFWPseudoAddressSpaceAux, 2);
OSMetaClassDefineReservedUnused(IOFWPseudoAddressSpaceAux, 3);
OSMetaClassDefineReservedUnused(IOFWPseudoAddressSpaceAux, 4);
OSMetaClassDefineReservedUnused(IOFWPseudoAddressSpaceAux, 5);
OSMetaClassDefineReservedUnused(IOFWPseudoAddressSpaceAux, 6);
OSMetaClassDefineReservedUnused(IOFWPseudoAddressSpaceAux, 7);
OSMetaClassDefineReservedUnused(IOFWPseudoAddressSpaceAux, 8);
OSMetaClassDefineReservedUnused(IOFWPseudoAddressSpaceAux, 9);
#pragma mark -
bool IOFWPseudoAddressSpaceAux::init( IOFWAddressSpace * primary )
{
bool success = true;
if( !IOFWAddressSpaceAux::init( primary ) )
success = false;
if( success )
{
fMembers = (MemberVariables*)IOMalloc( sizeof(MemberVariables) );
if( fMembers == NULL )
success = false;
}
if( success )
{
bzero( fMembers, sizeof(MemberVariables) );
}
if( !success )
{
if( fMembers != NULL )
{
IOFree( fMembers, sizeof(MemberVariables) );
fMembers = NULL;
}
}
return success;
}
void IOFWPseudoAddressSpaceAux::free()
{
if( fMembers != NULL )
{
IOFree( fMembers, sizeof(MemberVariables) );
fMembers = NULL;
}
IOFWAddressSpaceAux::free();
}
void IOFWPseudoAddressSpaceAux::handleARxReqIntComplete( void )
{
if( fMembers->fARxReqIntCompleteHandler != NULL )
{
(*fMembers->fARxReqIntCompleteHandler)( fMembers->fARxReqIntCompleteHandlerRefcon );
}
}
void IOFWPseudoAddressSpaceAux::setARxReqIntCompleteHandler( void * refcon, IOFWARxReqIntCompleteHandler handler )
{
fMembers->fARxReqIntCompleteHandler = handler;
fMembers->fARxReqIntCompleteHandlerRefcon = refcon;
}
#pragma mark -
OSDefineMetaClassAndStructors(IOFWPseudoAddressSpace, IOFWAddressSpace)
OSMetaClassDefineReservedUnused(IOFWPseudoAddressSpace, 0);
OSMetaClassDefineReservedUnused(IOFWPseudoAddressSpace, 1);
#pragma mark -
IOReturn IOFWPseudoAddressSpace::allocateAddress(FWAddress *addr, UInt32 lenDummy)
{
return fControl->allocatePseudoAddress( addr, lenDummy );
}
void IOFWPseudoAddressSpace::freeAddress(FWAddress addr, UInt32 lenDummy)
{
fControl->freePseudoAddress( addr, lenDummy );
}
UInt32 IOFWPseudoAddressSpace::simpleReader(void *refcon, UInt16 nodeID, IOFWSpeed &speed,
FWAddress addr, UInt32 len, IOMemoryDescriptor **buf,
IOByteCount * offset, IOFWRequestRefCon reqrefcon)
{
IOFWPseudoAddressSpace * space = (IOFWPseudoAddressSpace *)refcon;
*buf = space->fDesc;
*offset = addr.addressLo - space->fBase.addressLo;
return kFWResponseComplete;
}
UInt32 IOFWPseudoAddressSpace::simpleWriter(void *refcon, UInt16 nodeID, IOFWSpeed &speed,
FWAddress addr, UInt32 len, const void *buf, IOFWRequestRefCon reqrefcon)
{
IOFWPseudoAddressSpace * space = (IOFWPseudoAddressSpace *)refcon;
space->fDesc->writeBytes(addr.addressLo - space->fBase.addressLo, buf, len);
return kFWResponseComplete;
}
IOFWPseudoAddressSpace *
IOFWPseudoAddressSpace::simpleRead(IOFireWireBus *control,
FWAddress *addr, UInt32 len, const void *data)
{
IOFWPseudoAddressSpace * me = new IOFWPseudoAddressSpace;
do
{
if(!me)
break;
if(!me->initAll(control, addr, len, simpleReader, NULL, (void *)me))
{
me->release();
me = NULL;
break;
}
me->fDesc = IOMemoryDescriptor::withAddress((void *)data, len, kIODirectionOut);
if(!me->fDesc)
{
me->release();
me = NULL;
}
} while(false);
return me;
}
IOFWPseudoAddressSpace *
IOFWPseudoAddressSpace::simpleReadFixed(IOFireWireBus *control,
FWAddress addr, UInt32 len, const void *data)
{
IOFWPseudoAddressSpace * me = new IOFWPseudoAddressSpace;
do
{
if(!me)
break;
if(!me->initFixed(control, addr, len, simpleReader, NULL, (void *)me))
{
me->release();
me = NULL;
break;
}
me->fDesc = IOMemoryDescriptor::withAddress((void *)data, len, kIODirectionOut);
if(!me->fDesc)
{
me->release();
me = NULL;
}
} while(false);
return me;
}
IOFWPseudoAddressSpace *
IOFWPseudoAddressSpace::simpleRWFixed(IOFireWireBus *control,
FWAddress addr, UInt32 len, const void *data)
{
IOFWPseudoAddressSpace * me = new IOFWPseudoAddressSpace;
do
{
if(!me)
break;
if(!me->initFixed(control, addr, len, simpleReader, simpleWriter, (void *)me))
{
me->release();
me = NULL;
break;
}
me->fDesc = IOMemoryDescriptor::withAddress((void *)data, len, kIODirectionOut);
if(!me->fDesc)
{
me->release();
me = NULL;
}
} while(false);
return me;
}
IOFWPseudoAddressSpace *IOFWPseudoAddressSpace::simpleRW(IOFireWireBus *control,
FWAddress *addr, UInt32 len, void *data)
{
IOFWPseudoAddressSpace * me = new IOFWPseudoAddressSpace;
do
{
if(!me)
break;
if(!me->initAll(control, addr, len, simpleReader, simpleWriter, (void *)me))
{
me->release();
me = NULL;
break;
}
me->fDesc = IOMemoryDescriptor::withAddress(data, len, kIODirectionOut);
if(!me->fDesc)
{
me->release();
me = NULL;
}
} while(false);
return me;
}
IOFWPseudoAddressSpace *IOFWPseudoAddressSpace::simpleRW(IOFireWireBus *control,
FWAddress *addr, IOMemoryDescriptor * data)
{
IOFWPseudoAddressSpace * me = new IOFWPseudoAddressSpace;
do
{
if(!me)
break;
if(!me->initAll(control, addr, data->getLength(), simpleReader, simpleWriter, (void *)me))
{
me->release();
me = NULL;
break;
}
data->retain();
me->fDesc = data;
} while(false);
return me;
}
bool IOFWPseudoAddressSpace::initAll(IOFireWireBus *control, FWAddress *addr, UInt32 len,
FWReadCallback reader, FWWriteCallback writer, void *refCon)
{
if(!IOFWAddressSpace::init(control))
return false;
if(allocateAddress(addr, len) != kIOReturnSuccess)
return false;
fBase = *addr;
fBase.addressHi &= 0xFFFF; fLen = len;
fDesc = NULL; fRefCon = refCon;
fReader = reader;
fWriter = writer;
return true;
}
bool IOFWPseudoAddressSpace::initFixed(IOFireWireBus *control, FWAddress addr, UInt32 len,
FWReadCallback reader, FWWriteCallback writer, void *refCon)
{
if( !IOFWAddressSpace::init(control) )
return false;
if( addr.addressHi != kCSRRegisterSpaceBaseAddressHi )
return false;
fBase = addr;
fLen = len;
fDesc = NULL; fRefCon = refCon;
fReader = reader;
fWriter = writer;
return true;
}
IOFWAddressSpaceAux * IOFWPseudoAddressSpace::createAuxiliary( void )
{
IOFWPseudoAddressSpaceAux * auxiliary;
auxiliary = new IOFWPseudoAddressSpaceAux;
if( auxiliary != NULL && !auxiliary->init(this) )
{
auxiliary->release();
auxiliary = NULL;
}
return auxiliary;
}
void IOFWPseudoAddressSpace::free()
{
if(fDesc)
fDesc->release();
if(fBase.addressHi != kCSRRegisterSpaceBaseAddressHi)
freeAddress(fBase, fLen);
IOFWAddressSpace::free();
}
UInt32 IOFWPseudoAddressSpace::doRead( UInt16 nodeID, IOFWSpeed &speed, FWAddress addr, UInt32 len,
IOMemoryDescriptor **buf, IOByteCount * offset, IOFWRequestRefCon refcon)
{
if( !isTrustedNode( nodeID ) )
return kFWResponseAddressError;
if(addr.addressHi != fBase.addressHi)
return kFWResponseAddressError;
if(addr.addressLo < fBase.addressLo)
return kFWResponseAddressError;
if(addr.addressLo + len > fBase.addressLo+fLen)
return kFWResponseAddressError;
if(!fReader)
return kFWResponseTypeError;
return fReader(fRefCon, nodeID, speed, addr, len, buf, offset, refcon);
}
UInt32 IOFWPseudoAddressSpace::doWrite(UInt16 nodeID, IOFWSpeed &speed, FWAddress addr, UInt32 len,
const void *buf, IOFWRequestRefCon refcon)
{
if( !isTrustedNode( nodeID ) )
return kFWResponseAddressError;
if(addr.addressHi != fBase.addressHi)
return kFWResponseAddressError;
if(addr.addressLo < fBase.addressLo)
return kFWResponseAddressError;
if(addr.addressLo + len > fBase.addressLo+fLen)
return kFWResponseAddressError;
if(!fWriter)
return kFWResponseTypeError;
return fWriter(fRefCon, nodeID, speed, addr, len, buf, refcon);
}
UInt32 IOFWPseudoAddressSpace::contains(FWAddress addr)
{
UInt32 offset;
if(addr.addressHi != fBase.addressHi)
return 0;
if(addr.addressLo < fBase.addressLo)
return 0;
offset = addr.addressLo - fBase.addressLo;
if(offset > fLen)
return 0;
return fLen - offset;
}