1/* 2 * Copyright (c) 1998-2007 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 29#include <IOKit/IOSubMemoryDescriptor.h> 30 31#include "IOKitKernelInternal.h" 32 33#define super IOMemoryDescriptor 34 35OSDefineMetaClassAndStructors(IOSubMemoryDescriptor, IOMemoryDescriptor) 36 37IOReturn IOSubMemoryDescriptor::redirect( task_t safeTask, bool doRedirect ) 38{ 39#ifdef __LP64__ 40 super::redirect( safeTask, doRedirect ); 41#endif /* __LP64__ */ 42 return( _parent->redirect( safeTask, doRedirect )); 43} 44 45IOSubMemoryDescriptor * 46IOSubMemoryDescriptor::withSubRange(IOMemoryDescriptor * of, 47 IOByteCount offset, 48 IOByteCount length, 49 IOOptionBits options) 50{ 51 IOSubMemoryDescriptor *self = new IOSubMemoryDescriptor; 52 53 if (self && !self->initSubRange(of, offset, length, (IODirection) options)) { 54 self->release(); 55 self = 0; 56 } 57 return self; 58} 59 60bool IOSubMemoryDescriptor::initSubRange( IOMemoryDescriptor * parent, 61 IOByteCount offset, IOByteCount length, 62 IODirection direction ) 63{ 64 if( parent && ((offset + length) > parent->getLength())) 65 return( false); 66 67 /* 68 * We can check the _parent instance variable before having ever set it 69 * to an initial value because I/O Kit guarantees that all our instance 70 * variables are zeroed on an object's allocation. 71 */ 72 73 if( !_parent) { 74 if( !super::init()) 75 return( false ); 76 } else { 77 /* 78 * An existing memory descriptor is being retargeted to 79 * point to somewhere else. Clean up our present state. 80 */ 81 82 _parent->release(); 83 } 84 85 if (parent) { 86 parent->retain(); 87 _tag = parent->getTag(); 88 } 89 else { 90 _tag = 0; 91 } 92 _parent = parent; 93 _start = offset; 94 _length = length; 95 _flags = direction; 96#ifndef __LP64__ 97 _direction = (IODirection) (_flags & kIOMemoryDirectionMask); 98#endif /* !__LP64__ */ 99 100 return( true ); 101} 102 103void IOSubMemoryDescriptor::free( void ) 104{ 105 if( _parent) 106 _parent->release(); 107 108 super::free(); 109} 110 111addr64_t 112IOSubMemoryDescriptor::getPhysicalSegment(IOByteCount offset, IOByteCount * length, IOOptionBits options) 113{ 114 addr64_t address; 115 IOByteCount actualLength; 116 117 assert(offset <= _length); 118 119 if( length) 120 *length = 0; 121 122 if( offset >= _length) 123 return( 0 ); 124 125 address = _parent->getPhysicalSegment( offset + _start, &actualLength, options ); 126 127 if( address && length) 128 *length = min( _length - offset, actualLength ); 129 130 return( address ); 131} 132 133IOReturn IOSubMemoryDescriptor::setPurgeable( IOOptionBits newState, 134 IOOptionBits * oldState ) 135{ 136 IOReturn err; 137 138 err = _parent->setPurgeable( newState, oldState ); 139 140 return( err ); 141} 142 143IOReturn IOSubMemoryDescriptor::prepare( 144 IODirection forDirection) 145{ 146 IOReturn err; 147 148 err = _parent->prepare( forDirection); 149 150 return( err ); 151} 152 153IOReturn IOSubMemoryDescriptor::complete( 154 IODirection forDirection) 155{ 156 IOReturn err; 157 158 err = _parent->complete( forDirection); 159 160 return( err ); 161} 162 163IOMemoryMap * IOSubMemoryDescriptor::makeMapping( 164 IOMemoryDescriptor * owner, 165 task_t intoTask, 166 IOVirtualAddress address, 167 IOOptionBits options, 168 IOByteCount offset, 169 IOByteCount length ) 170{ 171 IOMemoryMap * mapping = 0; 172 173#ifndef __LP64__ 174 if (!(kIOMap64Bit & options)) 175 { 176 panic("IOSubMemoryDescriptor::makeMapping !64bit"); 177 } 178#endif /* !__LP64__ */ 179 180 mapping = (IOMemoryMap *) _parent->makeMapping( 181 owner, 182 intoTask, 183 address, 184 options, _start + offset, length ); 185 186 return( mapping ); 187} 188 189uint64_t 190IOSubMemoryDescriptor::getPreparationID( void ) 191{ 192 uint64_t pID; 193 194 if (!super::getKernelReserved()) 195 return (kIOPreparationIDUnsupported); 196 197 pID = _parent->getPreparationID(); 198 if (reserved->kernReserved[0] != pID) 199 { 200 reserved->kernReserved[0] = pID; 201 reserved->preparationID = kIOPreparationIDUnprepared; 202 super::setPreparationID(); 203 } 204 205 return (super::getPreparationID()); 206} 207 208