IOFWSimplePhysicalAddressSpace.cpp [plain text]
#ifndef _OPEN_SOURCE_
#import <IOKit/IOLib.h>
#import "IOFireWireController.h"
#import "IOFWSimplePhysicalAddressSpace.h"
OSDefineMetaClassAndStructors( IOFWSimplePhysicalAddressSpace, IOFWPhysicalAddressSpace )
OSMetaClassDefineReservedUnused(IOFWSimplePhysicalAddressSpace, 0);
OSMetaClassDefineReservedUnused(IOFWSimplePhysicalAddressSpace, 1);
OSMetaClassDefineReservedUnused(IOFWSimplePhysicalAddressSpace, 2);
OSMetaClassDefineReservedUnused(IOFWSimplePhysicalAddressSpace, 3);
OSMetaClassDefineReservedUnused(IOFWSimplePhysicalAddressSpace, 4);
OSMetaClassDefineReservedUnused(IOFWSimplePhysicalAddressSpace, 5);
OSMetaClassDefineReservedUnused(IOFWSimplePhysicalAddressSpace, 6);
OSMetaClassDefineReservedUnused(IOFWSimplePhysicalAddressSpace, 7);
OSMetaClassDefineReservedUnused(IOFWSimplePhysicalAddressSpace, 8);
OSMetaClassDefineReservedUnused(IOFWSimplePhysicalAddressSpace, 9);
struct MemberVariables
{
IODirection fDirection;
bool fContiguous;
IOBufferMemoryDescriptor * fDescriptor;
bool fDescriptorPrepared;
IOMemoryMap * fMap;
IOVirtualAddress fVirtualAddress;
UInt32 fLength;
};
#define _members ((MemberVariables*)fSimplePhysSpaceMembers)
bool IOFWSimplePhysicalAddressSpace::init( IOFireWireBus * control, vm_size_t size, IODirection direction, bool contiguous )
{
bool success = IOFWPhysicalAddressSpace::init( control );
fSimplePhysSpaceMembers = NULL;
if( success )
{
success = createMemberVariables();
}
if( success )
{
_members->fLength = size;
_members->fDirection = direction;
_members->fContiguous = contiguous;
}
if( success )
{
IOReturn status = allocateMemory();
if( status != kIOReturnSuccess )
success = false;
}
return success;
}
bool IOFWSimplePhysicalAddressSpace::createMemberVariables( void )
{
bool success = true;
if( fSimplePhysSpaceMembers == NULL )
{
if( success )
{
fSimplePhysSpaceMembers = IOMalloc( sizeof(MemberVariables) );
if( fSimplePhysSpaceMembers == NULL )
success = false;
}
if( success )
{
bzero( fSimplePhysSpaceMembers, sizeof(MemberVariables) );
_members->fLength = 0;
_members->fDirection = kIODirectionNone;
_members->fDescriptor = NULL;
_members->fDescriptorPrepared = false;
_members->fMap = NULL;
_members->fVirtualAddress = 0;
_members->fContiguous = false;
}
if( !success )
{
destroyMemberVariables();
}
}
return success;
}
void IOFWSimplePhysicalAddressSpace::destroyMemberVariables( void )
{
if( fSimplePhysSpaceMembers != NULL )
{
IOFree( fSimplePhysSpaceMembers, sizeof(MemberVariables) );
fSimplePhysSpaceMembers = NULL;
}
}
void IOFWSimplePhysicalAddressSpace::free( void )
{
setDMACommand( NULL );
deallocateMemory();
destroyMemberVariables();
IOFWPhysicalAddressSpace::free();
}
#pragma mark -
IOReturn IOFWSimplePhysicalAddressSpace::allocateMemory( void )
{
IOReturn status = kIOReturnSuccess;
if( _members->fLength == 0 )
{
status = kIOReturnBadArgument;
}
if( status == kIOReturnSuccess )
{
IOOptionBits options = 0;
if( _members->fContiguous )
{
options |= kIOMemoryPhysicallyContiguous;
}
UInt64 mask = fControl->getFireWirePhysicalAddressMask();
_members->fDescriptor = IOBufferMemoryDescriptor::inTaskWithPhysicalMask(
kernel_task, options, _members->fLength, mask ); if( _members->fDescriptor == NULL )
status = kIOReturnNoMemory;
}
if( status == kIOReturnSuccess )
{
((IOBufferMemoryDescriptor*)_members->fDescriptor)->setLength( _members->fLength );
status = _members->fDescriptor->prepare( _members->fDirection );
}
if( status == kIOReturnSuccess )
{
_members->fDescriptorPrepared = true;
}
IODMACommand * dma_command = NULL;
if( status == kIOReturnSuccess )
{
UInt32 address_bits = fControl->getFireWirePhysicalAddressBits();
dma_command = IODMACommand::withSpecification(
kIODMACommandOutputHost64, address_bits, _members->fLength, (IODMACommand::MappingOptions)(IODMACommand::kMapped | IODMACommand::kIterateOnly), _members->fLength, 0, NULL, NULL ); if( dma_command == NULL )
status = kIOReturnNoMemory;
}
if( status == kIOReturnSuccess )
{
setDMACommand( dma_command );
dma_command->release();
status = setMemoryDescriptor( _members->fDescriptor );
}
if( status == kIOReturnSuccess )
{
_members->fMap = _members->fDescriptor->map();
if( _members->fMap == NULL )
{
status = kIOReturnNoMemory;
}
}
if( status == kIOReturnSuccess )
{
_members->fVirtualAddress = _members->fMap->getVirtualAddress();
if( _members->fVirtualAddress == NULL )
{
status = kIOReturnNoMemory;
}
}
if( status == kIOReturnSuccess )
{
bzero( (void *)_members->fVirtualAddress, _members->fLength );
}
return status;
}
void IOFWSimplePhysicalAddressSpace::deallocateMemory( void )
{
if( _members->fMap != NULL )
{
_members->fMap->release();
_members->fMap = NULL;
}
if( _members->fDescriptorPrepared )
{
_members->fDescriptor->complete();
_members->fDescriptorPrepared = false;
}
if( _members->fDescriptor )
{
_members->fDescriptor->release();
_members->fDescriptor = NULL;
}
_members->fVirtualAddress = 0;
}
#pragma mark -
IOVirtualAddress IOFWSimplePhysicalAddressSpace::getVirtualAddress( void )
{
return _members->fVirtualAddress;
}
#endif