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 35 OSDefineMetaClassAndStructors(IOSubMemoryDescriptor, IOMemoryDescriptor) 36 37 IOReturn 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 45 IOSubMemoryDescriptor * 46 IOSubMemoryDescriptor::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 60 bool IOSubMemoryDescriptor::initSubRange( IOMemoryDescriptor * parent, 61 IOByteCount offset, IOByteCount length, 62 IODirection direction ) 63 { 64 if( !parent) 65 return( false); 66 67 if( (offset + length) > parent->getLength()) 68 return( false); 69 70 /* 71 * We can check the _parent instance variable before having ever set it 72 * to an initial value because I/O Kit guarantees that all our instance 73 * variables are zeroed on an object's allocation. 74 */ 75 76 if( !_parent) { 77 if( !super::init()) 78 return( false ); 79 } else { 80 /* 81 * An existing memory descriptor is being retargeted to 82 * point to somewhere else. Clean up our present state. 83 */ 84 85 _parent->release(); 86 _parent = 0; 87 } 88 89 parent->retain(); 90 _parent = parent; 91 _start = offset; 92 _length = length; 93 _flags = direction; 94 #ifndef __LP64__ 95 _direction = (IODirection) (_flags & kIOMemoryDirectionMask); 96 #endif /* !__LP64__ */ 97 _tag = parent->getTag(); 98 99 return( true ); 100 } 101 102 void IOSubMemoryDescriptor::free( void ) 103 { 104 if( _parent) 105 _parent->release(); 106 107 super::free(); 108 } 109 110 addr64_t 111 IOSubMemoryDescriptor::getPhysicalSegment(IOByteCount offset, IOByteCount * length, IOOptionBits options) 112 { 113 addr64_t address; 114 IOByteCount actualLength; 115 116 assert(offset <= _length); 117 118 if( length) 119 *length = 0; 120 121 if( offset >= _length) 122 return( 0 ); 123 124 address = _parent->getPhysicalSegment( offset + _start, &actualLength, options ); 125 126 if( address && length) 127 *length = min( _length - offset, actualLength ); 128 129 return( address ); 130 } 131 132 IOReturn IOSubMemoryDescriptor::setPurgeable( IOOptionBits newState, 133 IOOptionBits * oldState ) 134 { 135 IOReturn err; 136 137 err = _parent->setPurgeable( newState, oldState ); 138 139 return( err ); 140 } 141 142 IOReturn IOSubMemoryDescriptor::prepare( 143 IODirection forDirection) 144 { 145 IOReturn err; 146 147 err = _parent->prepare( forDirection); 148 149 return( err ); 150 } 151 152 IOReturn IOSubMemoryDescriptor::complete( 153 IODirection forDirection) 154 { 155 IOReturn err; 156 157 err = _parent->complete( forDirection); 158 159 return( err ); 160 } 161 162 IOMemoryMap * IOSubMemoryDescriptor::makeMapping( 163 IOMemoryDescriptor * owner, 164 task_t intoTask, 165 IOVirtualAddress address, 166 IOOptionBits options, 167 IOByteCount offset, 168 IOByteCount length ) 169 { 170 IOMemoryMap * mapping = 0; 171 172 #ifndef __LP64__ 173 if (!(kIOMap64Bit & options)) 174 { 175 panic("IOSubMemoryDescriptor::makeMapping !64bit"); 176 } 177 #endif /* !__LP64__ */ 178 179 mapping = (IOMemoryMap *) _parent->makeMapping( 180 owner, 181 intoTask, 182 address, 183 options, _start + offset, length ); 184 185 return( mapping ); 186 } 187 188 uint64_t 189 IOSubMemoryDescriptor::getPreparationID( void ) 190 { 191 return (_parent->getPreparationID()); 192 } 193 194