/* * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * The contents of this file constitute Original Code as defined in and * are subject to the Apple Public Source License Version 1.1 (the * "License"). You may not use this file except in compliance with the * License. Please obtain a copy of the License at * http://www.apple.com/publicsource and read it before using this file. * * This Original Code and all software distributed under the License are * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the * License for the specific language governing rights and limitations * under the License. * * @APPLE_LICENSE_HEADER_END@ */ /* * IOFireWireLibPhysicalAddressSpace.cpp * IOFireWireLib * * Created by NWG on Tue Dec 12 2000. * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. * */ #include "IOFireWireLibPriv.h" #include "IOFireWireLibPhysAddrSpace.h" #define MIN(a,b) ((a < b) ? a : b) // COM IOFireWirePhysicalAddressSpaceInterface IOFireWirePhysicalAddressSpaceImp::sInterface = { INTERFACEIMP_INTERFACE, 1, 0, //vers, rev & IOFireWirePhysicalAddressSpaceImp::SGetPhysicalSegments, & IOFireWirePhysicalAddressSpaceImp::SGetPhysicalSegment, & IOFireWirePhysicalAddressSpaceImp::SGetPhysicalAddress, & IOFireWirePhysicalAddressSpaceImp::SGetFWAddress, & IOFireWirePhysicalAddressSpaceImp::SGetBuffer, & IOFireWirePhysicalAddressSpaceImp::SGetBufferSize } ; HRESULT IOFireWirePhysicalAddressSpaceImp::QueryInterface(REFIID iid, void **ppv) { HRESULT result = S_OK ; *ppv = nil ; CFUUIDRef interfaceID = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault, iid) ; if ( CFEqual(interfaceID, IUnknownUUID) || CFEqual(interfaceID, kIOFireWirePhysicalAddressSpaceInterfaceID) ) { *ppv = & mInterface ; AddRef() ; } else { *ppv = nil ; result = E_NOINTERFACE ; } CFRelease(interfaceID) ; return result ; } IUnknownVTbl** IOFireWirePhysicalAddressSpaceImp::Alloc( IOFireWireDeviceInterfaceImp& inUserClient, FWKernPhysicalAddrSpaceRef inAddrSpaceRef, UInt32 inSize, void* inBackingStore, UInt32 inFlags) { IUnknownVTbl** interface = nil ; IOFireWirePhysicalAddressSpaceImp* me = new IOFireWirePhysicalAddressSpaceImp(inUserClient, inAddrSpaceRef, inSize, inBackingStore, inFlags) ; IOReturn result = me->Init() ; // printf("IOFireWirePhysicalAddressSpaceImp::Alloc: init returned %08lX\n", result) ; if (kIOReturnSuccess != result) { delete me ; me = nil ; interface = nil ; } if (me) { // me->AddRef(); interface = (IUnknownVTbl**) &me->mInterface.pseudoVTable; } return interface ; } #pragma mark - #pragma mark --static methods // // static methods // void IOFireWirePhysicalAddressSpaceImp::SGetPhysicalSegments( IOFireWireLibPhysicalAddressSpaceRef self, UInt32* ioSegmentCount, IOByteCount outSegments[], IOPhysicalAddress outAddresses[]) { GetThis(self)->GetPhysicalSegments(ioSegmentCount, outSegments, outAddresses) ; } IOPhysicalAddress IOFireWirePhysicalAddressSpaceImp::SGetPhysicalSegment( IOFireWireLibPhysicalAddressSpaceRef self, IOByteCount offset, IOByteCount* length) { return GetThis(self)->GetPhysicalSegment(offset, length) ; } IOPhysicalAddress IOFireWirePhysicalAddressSpaceImp::SGetPhysicalAddress( IOFireWireLibPhysicalAddressSpaceRef self) { return GetThis(self)->GetPhysicalAddress() ; } void IOFireWirePhysicalAddressSpaceImp::SGetFWAddress(IOFireWireLibPhysicalAddressSpaceRef self, FWAddress* outAddr ) { bcopy(& GetThis(self)->GetFWAddress(), outAddr, sizeof(*outAddr)) ; } void* IOFireWirePhysicalAddressSpaceImp::SGetBuffer(IOFireWireLibPhysicalAddressSpaceRef self) { return GetThis(self)->GetBuffer() ; } const UInt32 IOFireWirePhysicalAddressSpaceImp::SGetBufferSize(IOFireWireLibPhysicalAddressSpaceRef self) { return GetThis(self)->GetBufferSize() ; } #pragma mark - #pragma mark --ctor/dtor // // === ctor/dtor ============================== // IOFireWirePhysicalAddressSpaceImp::IOFireWirePhysicalAddressSpaceImp( IOFireWireDeviceInterfaceImp & inUserClient, FWKernPhysicalAddrSpaceRef inKernPhysicalAddrSpaceRef, UInt32 inSize, void* inBackingStore, UInt32 inFlags): IOFireWireIUnknown(), mUserClient(inUserClient), mKernPhysicalAddrSpaceRef(inKernPhysicalAddrSpaceRef), mSize(inSize), mBackingStore(inBackingStore), mSegments(0), mSegmentLengths(0), mSegmentCount(0) { inUserClient.AddRef() ; // COM bits mInterface.pseudoVTable = (IUnknownVTbl*) & sInterface ; mInterface.obj = this ; } IOFireWirePhysicalAddressSpaceImp::~IOFireWirePhysicalAddressSpaceImp() { // call user client to delete our addr space ref here (if not yet released) IOConnectMethodScalarIScalarO( mUserClient.GetUserClientConnection(), kFWPhysicalAddrSpace_Release, 1, 0, mKernPhysicalAddrSpaceRef) ; delete[] mSegments ; delete[] mSegmentLengths ; mUserClient.Release() ; } // // === virtual members ======================== // IOReturn IOFireWirePhysicalAddressSpaceImp::Init() { IOReturn result = kIOReturnSuccess ; if (!mKernPhysicalAddrSpaceRef) result = kIOReturnError ; // fprintf(stderr, "mKernPhysicalAddrSpaceRef = %08lX\n", mKernPhysicalAddrSpaceRef) ; if (kIOReturnSuccess == result) result = IOConnectMethodScalarIScalarO( mUserClient.GetUserClientConnection(), kFWPhysicalAddrSpace_GetSegmentCount, 1, 1, mKernPhysicalAddrSpaceRef, & mSegmentCount) ; // fprintf(stderr, "kFWPhysicalAddrSpace_GetSegmentCount returned %08lX, count=%i\n", result, mSegmentCount) ; if (mSegmentCount > 0) { mSegments = new IOPhysicalAddress[mSegmentCount] ; mSegmentLengths = new IOByteCount[mSegmentCount] ; if (!mSegments || !mSegmentLengths) { delete mSegments ; delete mSegmentLengths ; result = kIOReturnNoMemory ; } } if (kIOReturnSuccess == result) { UInt32 newSegmentCount ; result = IOConnectMethodScalarIScalarO( mUserClient.GetUserClientConnection(), kFWPhysicalAddrSpace_GetSegments, 4, 1, mKernPhysicalAddrSpaceRef, mSegmentCount, mSegments, mSegmentLengths, & newSegmentCount) ; mSegmentCount = newSegmentCount ; // fprintf(stderr, "kFWPhysicalAddrSpace_GetSegments returned %08lX, count=%08lX\n", result, newSegmentCount) ; // for(UInt32 debugIndex=0; debugIndex0) { IOByteCount traversed = mSegmentLengths[0] ; UInt32 currentSegment = 0 ; while((traversed < offset) && (currentSegment < mSegmentCount)) { traversed += mSegmentLengths[currentSegment] ; currentSegment++ ; } if (currentSegment <= mSegmentCount) { *length = mSegmentLengths[currentSegment] ; result = mSegments[currentSegment] ; } } return result ; } IOPhysicalAddress IOFireWirePhysicalAddressSpaceImp::GetPhysicalAddress() { return mSegments[0] ; } const FWAddress& IOFireWirePhysicalAddressSpaceImp::GetFWAddress() { return mFWAddress ; } void* IOFireWirePhysicalAddressSpaceImp::GetBuffer() { return mBackingStore ; } const UInt32 IOFireWirePhysicalAddressSpaceImp::GetBufferSize() { return mSize ; }