1/*
2 * Copyright (c) 1998-2006 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License").  You may not use this file except in compliance with the
9 * License.  Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22
23
24// public
25#import <IOKit/IOLib.h>
26
27// private
28#include "IOFWSimpleContiguousPhysicalAddressSpace.h"
29
30// fun with binary compatibility
31
32OSDefineMetaClassAndStructors( IOFWSimpleContiguousPhysicalAddressSpace, IOFWSimplePhysicalAddressSpace )
33
34OSMetaClassDefineReservedUnused(IOFWSimpleContiguousPhysicalAddressSpace, 0);
35OSMetaClassDefineReservedUnused(IOFWSimpleContiguousPhysicalAddressSpace, 1);
36OSMetaClassDefineReservedUnused(IOFWSimpleContiguousPhysicalAddressSpace, 2);
37OSMetaClassDefineReservedUnused(IOFWSimpleContiguousPhysicalAddressSpace, 3);
38OSMetaClassDefineReservedUnused(IOFWSimpleContiguousPhysicalAddressSpace, 4);
39OSMetaClassDefineReservedUnused(IOFWSimpleContiguousPhysicalAddressSpace, 5);
40OSMetaClassDefineReservedUnused(IOFWSimpleContiguousPhysicalAddressSpace, 6);
41OSMetaClassDefineReservedUnused(IOFWSimpleContiguousPhysicalAddressSpace, 7);
42OSMetaClassDefineReservedUnused(IOFWSimpleContiguousPhysicalAddressSpace, 8);
43OSMetaClassDefineReservedUnused(IOFWSimpleContiguousPhysicalAddressSpace, 9);
44
45struct MemberVariables
46{
47	FWAddress	fFWPhysicalAddress;
48};
49
50#define _members ((MemberVariables*)fSimpleContigPhysSpaceMembers)
51
52// init
53//
54//
55
56bool IOFWSimpleContiguousPhysicalAddressSpace::init( IOFireWireBus * control, vm_size_t size, IODirection direction )
57{
58	fSimpleContigPhysSpaceMembers = NULL;
59
60	bool success = IOFWSimplePhysicalAddressSpace::init( control, size, direction, true );
61
62	if( success )
63	{
64		IOReturn status = cachePhysicalAddress();
65		if( status != kIOReturnSuccess )
66			success = false;
67	}
68
69	return success;
70}
71
72// free
73//
74//
75
76void IOFWSimpleContiguousPhysicalAddressSpace::free( void )
77{
78	IOFWSimplePhysicalAddressSpace::free();
79}
80
81// createMemberVariables
82//
83//
84
85bool IOFWSimpleContiguousPhysicalAddressSpace::createMemberVariables( void )
86{
87	bool success = true;
88
89	success = IOFWSimplePhysicalAddressSpace::createMemberVariables();
90
91	if( success && (fSimpleContigPhysSpaceMembers == NULL) )
92	{
93		// create member variables
94
95		if( success )
96		{
97			fSimpleContigPhysSpaceMembers = IOMalloc( sizeof(MemberVariables) );
98			if( fSimpleContigPhysSpaceMembers == NULL )
99				success = false;
100		}
101
102		// zero member variables
103
104		if( success )
105		{
106			bzero( fSimpleContigPhysSpaceMembers, sizeof(MemberVariables) );
107
108			// largely redundant
109			_members->fFWPhysicalAddress.nodeID = 0x0000;
110			_members->fFWPhysicalAddress.addressHi = 0x0000;
111			_members->fFWPhysicalAddress.addressLo = 0x00000000;
112		}
113
114		// clean up on failure
115
116		if( !success )
117		{
118			destroyMemberVariables();
119		}
120	}
121
122	return success;
123}
124
125// destroyMemberVariables
126//
127//
128
129void IOFWSimpleContiguousPhysicalAddressSpace::destroyMemberVariables( void )
130{
131	IOFWSimplePhysicalAddressSpace::destroyMemberVariables();
132
133	if( fSimpleContigPhysSpaceMembers != NULL )
134	{
135		IOFree( fSimpleContigPhysSpaceMembers, sizeof(MemberVariables) );
136		fSimpleContigPhysSpaceMembers = NULL;
137	}
138}
139
140#pragma mark -
141
142// cachePhysicalAddress
143//
144//
145
146IOReturn IOFWSimpleContiguousPhysicalAddressSpace::cachePhysicalAddress( void )
147{
148	IOReturn status = kIOReturnSuccess;
149
150	UInt32 segment_count = 0;
151	FWSegment	segments[ 2 ];
152	if( status == kIOReturnSuccess )
153	{
154		UInt64 offset_64 = 0;
155		segment_count = 2;
156		status = getSegments( &offset_64, segments, &segment_count );
157	}
158
159	// sanity checks for contiguous allocation
160	if( status == kIOReturnSuccess )
161	{
162		if( segment_count > 2 || segment_count == 0 )
163		{
164			status = kIOReturnNoResources;
165		}
166	}
167
168	if( status == kIOReturnSuccess )
169	{
170		if(  segments[0].length < getLength() )
171		{
172			status = kIOReturnNoResources;
173		}
174	}
175
176	if( status == kIOReturnSuccess )
177	{
178		_members->fFWPhysicalAddress = segments[0].address;
179	}
180
181//	IOLog( "IOFWSimpleContiguousPhysicalAddressSpace::cachePhysicalAddress - 0x%04x %08lx\n",
182//					_members->fFWPhysicalAddress.addressHi, _members->fFWPhysicalAddress.addressLo );
183
184	return status;
185}
186
187// getPhysicalAddress
188//
189//
190
191FWAddress IOFWSimpleContiguousPhysicalAddressSpace::getFWAddress( void )
192{
193	return _members->fFWPhysicalAddress;
194}
195