1/* 2 * Copyright (c) 1998-2014 Apple Inc. All rights reserved. 3 * 4 * @APPLE_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. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24#include <IOKit/storage/IOFilterScheme.h> 25 26#define super IOStorage 27OSDefineMetaClassAndStructors(IOFilterScheme, IOStorage) 28 29#ifndef __LP64__ 30extern IOStorageAttributes gIOStorageAttributesUnsupported; 31#endif /* !__LP64__ */ 32 33IOMedia * IOFilterScheme::getProvider() const 34{ 35 // 36 // Obtain this object's provider. We override the superclass's method 37 // to return a more specific subclass of OSObject -- an IOMedia. This 38 // method serves simply as a convenience to subclass developers. 39 // 40 41 return (IOMedia *) IOService::getProvider(); 42} 43 44bool IOFilterScheme::handleOpen(IOService * client, 45 IOOptionBits options, 46 void * argument) 47{ 48 // 49 // The handleOpen method grants or denies permission to access this object 50 // to an interested client. The argument is an IOStorageAccess value that 51 // specifies the level of access desired -- reader or reader-writer. 52 // 53 // This method can be invoked to upgrade or downgrade the access level for 54 // an existing client as well. The previous access level will prevail for 55 // upgrades that fail, of course. A downgrade should never fail. If the 56 // new access level should be the same as the old for a given client, this 57 // method will do nothing and return success. In all cases, one, singular 58 // close-per-client is expected for all opens-per-client received. 59 // 60 // This implementation replaces the IOService definition of handleOpen(). 61 // 62 // We are guaranteed that no other opens or closes will be processed until 63 // we make our decision, change our state, and return from this method. 64 // 65 66 return getProvider()->open(this, options, (uintptr_t) argument); 67} 68 69bool IOFilterScheme::handleIsOpen(const IOService * client) const 70{ 71 // 72 // The handleIsOpen method determines whether the specified client, or any 73 // client if none is specificed, presently has an open on this object. 74 // 75 // This implementation replaces the IOService definition of handleIsOpen(). 76 // 77 // We are guaranteed that no other opens or closes will be processed until 78 // we return from this method. 79 // 80 81 return getProvider()->isOpen(this); 82} 83 84void IOFilterScheme::handleClose(IOService * client, IOOptionBits options) 85{ 86 // 87 // The handleClose method closes the client's access to this object. 88 // 89 // This implementation replaces the IOService definition of handleClose(). 90 // 91 // We are guaranteed that no other opens or closes will be processed until 92 // we change our state and return from this method. 93 // 94 95 getProvider()->close(this, options); 96} 97 98void IOFilterScheme::read(IOService * client, 99 UInt64 byteStart, 100 IOMemoryDescriptor * buffer, 101 IOStorageAttributes * attributes, 102 IOStorageCompletion * completion) 103{ 104 // 105 // Read data from the storage object at the specified byte offset into the 106 // specified buffer, asynchronously. When the read completes, the caller 107 // will be notified via the specified completion action. 108 // 109 // The buffer will be retained for the duration of the read. 110 // 111 // For simple filter schemes, the default behavior is to simply pass the 112 // read through to the provider media. More complex filter schemes such 113 // as RAID will need to do extra processing here. 114 // 115 116#ifndef __LP64__ 117 if ( IOStorage::_expansionData ) 118 { 119 if ( attributes == &gIOStorageAttributesUnsupported ) 120 { 121 attributes = NULL; 122 } 123 else 124 { 125 IOStorage::read( client, byteStart, buffer, attributes, completion ); 126 127 return; 128 } 129 } 130#endif /* !__LP64__ */ 131 132 getProvider( )->read( this, byteStart, buffer, attributes, completion ); 133} 134 135void IOFilterScheme::write(IOService * client, 136 UInt64 byteStart, 137 IOMemoryDescriptor * buffer, 138 IOStorageAttributes * attributes, 139 IOStorageCompletion * completion) 140{ 141 // 142 // Write data into the storage object at the specified byte offset from the 143 // specified buffer, asynchronously. When the write completes, the caller 144 // will be notified via the specified completion action. 145 // 146 // The buffer will be retained for the duration of the write. 147 // 148 // For simple filter schemes, the default behavior is to simply pass the 149 // write through to the provider media. More complex filter schemes such 150 // as RAID will need to do extra processing here. 151 // 152 153#ifndef __LP64__ 154 if ( IOStorage::_expansionData ) 155 { 156 if ( attributes == &gIOStorageAttributesUnsupported ) 157 { 158 attributes = NULL; 159 } 160 else 161 { 162 IOStorage::write( client, byteStart, buffer, attributes, completion ); 163 164 return; 165 } 166 } 167#endif /* !__LP64__ */ 168 169 getProvider( )->write( this, byteStart, buffer, attributes, completion ); 170} 171 172IOReturn IOFilterScheme::synchronizeCache(IOService * client) 173{ 174 // 175 // Flush the cached data in the storage object, if any, synchronously. 176 // 177 178 return getProvider()->synchronizeCache(this); 179} 180 181IOReturn IOFilterScheme::unmap(IOService * client, 182 IOStorageExtent * extents, 183 UInt32 extentsCount, 184 UInt32 options) 185{ 186 // 187 // Delete unused data from the storage object at the specified byte offsets, 188 // synchronously. 189 // 190 191 return getProvider( )->unmap( this, extents, extentsCount, options ); 192} 193 194bool IOFilterScheme::lockPhysicalExtents(IOService * client) 195{ 196 // 197 // Lock the contents of the storage object against relocation temporarily, 198 // for the purpose of getting physical extents. 199 // 200 201 return getProvider( )->lockPhysicalExtents( this ); 202} 203 204IOStorage * IOFilterScheme::copyPhysicalExtent(IOService * client, 205 UInt64 * byteStart, 206 UInt64 * byteCount) 207{ 208 // 209 // Convert the specified byte offset into a physical byte offset, relative 210 // to a physical storage object. This call should only be made within the 211 // context of lockPhysicalExtents(). 212 // 213 214 return getProvider( )->copyPhysicalExtent( this, byteStart, byteCount ); 215} 216 217void IOFilterScheme::unlockPhysicalExtents(IOService * client) 218{ 219 // 220 // Unlock the contents of the storage object for relocation again. This 221 // call must balance a successful call to lockPhysicalExtents(). 222 // 223 224 getProvider( )->unlockPhysicalExtents( this ); 225} 226 227IOReturn IOFilterScheme::setPriority(IOService * client, 228 IOStorageExtent * extents, 229 UInt32 extentsCount, 230 IOStoragePriority priority) 231{ 232 // 233 // Reprioritize read or write requests at the specified byte offsets. 234 // 235 236 return getProvider( )->setPriority( this, extents, extentsCount, priority ); 237} 238 239OSMetaClassDefineReservedUnused(IOFilterScheme, 0); 240OSMetaClassDefineReservedUnused(IOFilterScheme, 1); 241OSMetaClassDefineReservedUnused(IOFilterScheme, 2); 242OSMetaClassDefineReservedUnused(IOFilterScheme, 3); 243OSMetaClassDefineReservedUnused(IOFilterScheme, 4); 244OSMetaClassDefineReservedUnused(IOFilterScheme, 5); 245OSMetaClassDefineReservedUnused(IOFilterScheme, 6); 246OSMetaClassDefineReservedUnused(IOFilterScheme, 7); 247OSMetaClassDefineReservedUnused(IOFilterScheme, 8); 248OSMetaClassDefineReservedUnused(IOFilterScheme, 9); 249OSMetaClassDefineReservedUnused(IOFilterScheme, 10); 250OSMetaClassDefineReservedUnused(IOFilterScheme, 11); 251OSMetaClassDefineReservedUnused(IOFilterScheme, 12); 252OSMetaClassDefineReservedUnused(IOFilterScheme, 13); 253OSMetaClassDefineReservedUnused(IOFilterScheme, 14); 254OSMetaClassDefineReservedUnused(IOFilterScheme, 15); 255OSMetaClassDefineReservedUnused(IOFilterScheme, 16); 256OSMetaClassDefineReservedUnused(IOFilterScheme, 17); 257OSMetaClassDefineReservedUnused(IOFilterScheme, 18); 258OSMetaClassDefineReservedUnused(IOFilterScheme, 19); 259OSMetaClassDefineReservedUnused(IOFilterScheme, 20); 260OSMetaClassDefineReservedUnused(IOFilterScheme, 21); 261OSMetaClassDefineReservedUnused(IOFilterScheme, 22); 262OSMetaClassDefineReservedUnused(IOFilterScheme, 23); 263OSMetaClassDefineReservedUnused(IOFilterScheme, 24); 264OSMetaClassDefineReservedUnused(IOFilterScheme, 25); 265OSMetaClassDefineReservedUnused(IOFilterScheme, 26); 266OSMetaClassDefineReservedUnused(IOFilterScheme, 27); 267OSMetaClassDefineReservedUnused(IOFilterScheme, 28); 268OSMetaClassDefineReservedUnused(IOFilterScheme, 29); 269OSMetaClassDefineReservedUnused(IOFilterScheme, 30); 270OSMetaClassDefineReservedUnused(IOFilterScheme, 31); 271 272#ifndef __LP64__ 273extern "C" void _ZN14IOFilterScheme4readEP9IOServiceyP18IOMemoryDescriptor19IOStorageCompletion( IOFilterScheme * scheme, IOService * client, UInt64 byteStart, IOMemoryDescriptor * buffer, IOStorageCompletion completion ) 274{ 275 scheme->read( client, byteStart, buffer, NULL, &completion ); 276} 277 278extern "C" void _ZN14IOFilterScheme5writeEP9IOServiceyP18IOMemoryDescriptor19IOStorageCompletion( IOFilterScheme * scheme, IOService * client, UInt64 byteStart, IOMemoryDescriptor * buffer, IOStorageCompletion completion ) 279{ 280 scheme->write( client, byteStart, buffer, NULL, &completion ); 281} 282#endif /* !__LP64__ */ 283