/* * Copyright (c) 1998-2015 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The 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, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ /*! * @header IOStorage * @abstract * This header contains the IOStorage class definition. */ #ifndef _IOSTORAGE_H #define _IOSTORAGE_H #include #include /*! * @defined kIOStorageClass * @abstract * The name of the IOStorage class. */ #define kIOStorageClass "IOStorage" /*! * @defined kIOStorageCategory * @abstract * kIOStorageCategory is a value for IOService's kIOMatchCategoryKey property. * @discussion * The kIOStorageCategory value is the standard value for the IOService property * kIOMatchCategoryKey ("IOMatchCategory") for all storage drivers. All storage * objects that expect to drive new content (that is, produce new media objects) * are expected to compete within the kIOStorageCategory namespace. * * See the IOService documentation for more information on match categories. */ #define kIOStorageCategory "IOStorage" /* (as IOMatchCategory) */ /*! * @defined kIOStorageFeaturesKey * @abstract * A property of any object in the storage stack. * @discussion * kIOStorageFeaturesKey is a property of any object in the storage stack that * wishes to express support of additional features, such as Force Unit Access. * It is typically defined in the device object below the block storage driver * object. It has an OSDictionary value, where each entry describes one given * feature. */ #define kIOStorageFeaturesKey "IOStorageFeatures" /*! * @defined kIOStorageFeatureBarrier * @abstract * Describes the presence of the Barrier feature. * @discussion * This property describes the ability of the storage stack to honor a write * barrier, guaranteeing that on power loss, writes after the barrier will not * be visible until all writes before the barrier are visible. It is one of the * feature entries listed under the top-level kIOStorageFeaturesKey property * table. It has an OSBoolean value. */ #define kIOStorageFeatureBarrier "Barrier" /*! * @defined kIOStorageFeatureForceUnitAccess * @abstract * Describes the presence of the Force Unit Access feature. * @discussion * This property describes the ability of the storage stack to force a request * to access the media. It is one of the feature entries listed under the top- * level kIOStorageFeaturesKey property table. It has an OSBoolean value. */ #define kIOStorageFeatureForceUnitAccess "Force Unit Access" /*! * @defined kIOStorageFeaturePriority * @abstract * Describes the presence of the Priority feature. * @discussion * This property describes the ability of the storage stack to enforce the * priority of a request. It is one of the feature entries listed under the * top-level kIOStorageFeaturesKey property table. It has an OSBoolean value. */ #define kIOStorageFeaturePriority "Priority" /*! * @defined kIOStorageFeatureUnmap * @abstract * Describes the presence of the Unmap feature. * @discussion * This property describes the ability of the storage stack to delete unused * data from the media. It is one of the feature entries listed under the top- * level kIOStorageFeaturesKey property table. It has an OSBoolean value. */ #define kIOStorageFeatureUnmap "Unmap" #ifdef KERNEL #ifdef __cplusplus /* * Kernel */ #include #include #include /*! * @enum IOStorageAccess * @discussion * The IOStorageAccess enumeration describes the possible access levels for open * requests. * @constant kIOStorageAccessNone * No access is requested; should not be passed to open(). * @constant kIOStorageAccessReader * Read-only access is requested. * @constant kIOStorageAccessWriter * write-only access is requested. * @constant kIOStorageAccessReaderWriter * Read and write access is requested. * @constant kIOStorageAccessSharedLock * Shared access is requested. * @constant kIOStorageAccessExclusiveLock * Exclusive access is requested. * @constant kIOStorageAccessInvalid * Invalid access is requested. * @constant kIOStorageAccessReserved * Reserved Access. */ enum { kIOStorageAccessNone = 0x00, kIOStorageAccessReader = 0x01, kIOStorageAccessWriter = 0x02, kIOStorageAccessReaderWriter = 0x03, kIOStorageAccessSharedLock = 0x04, kIOStorageAccessExclusiveLock = 0x08, kIOStorageAccessInvalid = 0x0D, kIOStorageAccessReserved = 0xFFFFFFF0 }; typedef UInt32 IOStorageAccess; /*! * @enum IOStorageOptions * @discussion * Options for read and write storage requests. * @constant kIOStorageOptionForceUnitAccess * Force the request to access the media. * @constant kIOStorageOptionIsEncrypted * The data is already encrypted. * @constant kIOStorageOptionIsStatic * The data is likely to remain unaltered. */ enum { kIOStorageOptionNone = 0x0000, kIOStorageOptionForceUnitAccess = 0x0001, kIOStorageOptionIsEncrypted = 0x0010, kIOStorageOptionIsStatic = 0x0020, kIOStorageOptionReserved = 0xFFCE }; typedef UInt16 IOStorageOptions; /*! * @enum IOStoragePriority * @discussion * Priority of read and write storage requests. The lower the value, the * higher the priority. * @constant kIOStoragePriorityHigh * This priority should only be used for I/O that is critical to system * responsiveness. * @constant kIOStoragePriorityDefault * This priority is for work requested by the user, but that is not the user's * current focus. * @constant kIOStoragePriorityLow * This priority is for short-running background work. * @constant kIOStoragePriorityBackground * This priority is for long-running, I/O intensive background work, such as * backups, search indexing, or file synchronization. */ enum { kIOStoragePriorityHigh = 63, /* 0 to 63 */ kIOStoragePriorityDefault = 127, /* 64 to 127 */ kIOStoragePriorityLow = 191, /* 128 to 191 */ kIOStoragePriorityBackground = 255 /* 192 to 255 */ }; typedef UInt8 IOStoragePriority; /*! * @enum IOStorageSynchronizeOptions * @discussion * Options for synchronize storage requests. * @constant kIOStorageSynchronizeOptionBarrier * Issue a write barrier only. */ enum { kIOStorageSynchronizeOptionNone = 0x00000000, kIOStorageSynchronizeOptionBarrier = 0x00000002, kIOStorageSynchronizeOptionReserved = 0xFFFFFFFD }; typedef UInt32 IOStorageSynchronizeOptions; /*! * @enum IOStorageUnmapOptions * @discussion * Options for unmap storage requests. */ enum { kIOStorageUnmapOptionReserved = 0xFFFFFFFF }; typedef UInt32 IOStorageUnmapOptions; /*! * @struct IOStorageAttributes * @discussion * Attributes of read and write storage requests. * @field options * Options for the request. See IOStorageOptions. * @field priority * Priority of the request. See IOStoragePriority. * @field bufattr * Reserved for future use. Set to zero. */ struct IOStorageAttributes { IOStorageOptions options; IOStoragePriority priority; UInt8 reserved0024; UInt32 reserved0032; UInt64 reserved0064; UInt64 adjustedOffset; bufattr_t bufattr; }; /*! * @struct IOStorageExtent * @discussion * Extent for unmap storage requests. * @field byteStart * Starting byte offset for the operation. * @field byteCount * Size of the operation. */ struct IOStorageExtent { UInt64 byteStart; UInt64 byteCount; }; /*! * @enum IOStorageProvisionTypes * @discussion * Device block provision types, such as mapped, deallocated, or anchored. See SCSI * SBC4 specifiction, LBA status descriptor for definitions. */ enum { kIOStorageProvisionTypeMapped = 0x00, kIOStorageProvisionTypeDeallocated = 0x01, kIOStorageProvisionTypeAnchored = 0x02 }; typedef UInt64 IOStorageGetProvisionStatusOptions; /*! * @struct IOStorageProvisionExtent * @discussion * Extent for provision status. * @field byteStart * Starting byte offset for the operation. * @field byteCount * Size of the operation. * @field provisionType * Block provision type. See IOStorageProvisionTypes. */ struct IOStorageProvisionExtent { UInt64 byteStart; UInt64 byteCount; UInt8 provisionType; UInt8 reserved[7]; }; /*! * @typedef IOStorageCompletionAction * @discussion * The IOStorageCompletionAction declaration describes the C (or C++) completion * routine that is called once an asynchronous storage operation completes. * @param target * Opaque client-supplied pointer (or an instance pointer for a C++ callback). * @param parameter * Opaque client-supplied pointer. * @param status * Status of the data transfer. * @param actualByteCount * Actual number of bytes transferred in the data transfer. */ typedef void (*IOStorageCompletionAction)(void * target, void * parameter, IOReturn status, UInt64 actualByteCount); /*! * @struct IOStorageCompletion * @discussion * The IOStorageCompletion structure describes the C (or C++) completion routine * that is called once an asynchronous storage operation completes. The values * passed for the target and parameter fields will be passed to the routine when * it is called. * @field target * Opaque client-supplied pointer (or an instance pointer for a C++ callback). * @field action * Completion routine to call on completion of the data transfer. * @field parameter * Opaque client-supplied pointer. */ struct IOStorageCompletion { void * target; IOStorageCompletionAction action; void * parameter; }; /*! * @class IOStorage * @abstract * The common base class for mass storage objects. * @discussion * The IOStorage class is the common base class for mass storage objects. It is * an abstract class that defines the open/close/read/write APIs that need to be * implemented in a given subclass. Synchronous versions of the read/write APIs * are provided here -- they are coded in such a way as to wrap the asynchronous * versions implemented in the subclass. */ class __exported IOStorage : public IOService { OSDeclareAbstractStructors(IOStorage); protected: struct ExpansionData { /* */ }; ExpansionData * _expansionData; /*! * @function handleOpen * @discussion * The handleOpen method grants or denies permission to access this object * to an interested client. The argument is an IOStorageAccess value that * specifies the level of access desired -- reader or reader-writer. * * This method can be invoked to upgrade or downgrade the access level for * an existing client as well. The previous access level will prevail for * upgrades that fail, of course. A downgrade should never fail. If the * new access level should be the same as the old for a given client, this * method will do nothing and return success. In all cases, one, singular * close-per-client is expected for all opens-per-client received. * @param client * Client requesting the open. * @param options * Options for the open. Set to zero. * @param access * Access level for the open. Set to kIOStorageAccessReader or * kIOStorageAccessReaderWriter. * @result * Returns true if the open was successful, false otherwise. */ virtual bool handleOpen(IOService * client, IOOptionBits options, void * access) APPLE_KEXT_OVERRIDE = 0; /*! * @function handleIsOpen * @discussion * The handleIsOpen method determines whether the specified client, or any * client if none is specified, presently has an open on this object. * @param client * Client to check the open state of. Set to zero to check the open state * of all clients. * @result * Returns true if the client was (or clients were) open, false otherwise. */ virtual bool handleIsOpen(const IOService * client) const APPLE_KEXT_OVERRIDE = 0; /*! * @function handleClose * @discussion * The handleClose method closes the client's access to this object. * @param client * Client requesting the close. * @param options * Options for the close. Set to zero. */ virtual void handleClose(IOService * client, IOOptionBits options) APPLE_KEXT_OVERRIDE = 0; public: #if TARGET_OS_OSX virtual bool attach(IOService * provider) APPLE_KEXT_OVERRIDE; #endif /* TARGET_OS_OSX */ /*! * @function complete * @discussion * Invokes the specified completion action of the read/write request. If * the completion action is unspecified, no action is taken. This method * serves simply as a convenience to storage subclass developers. * @param completion * Completion information for the data transfer. * @param status * Status of the data transfer. * @param actualByteCount * Actual number of bytes transferred in the data transfer. */ static void complete(IOStorageCompletion * completion, IOReturn status, UInt64 actualByteCount = 0); /*! * @function open * @discussion * Ask the storage object for permission to access its contents; the method * is equivalent to IOService::open(), but with the correct parameter types. * * This method may also be invoked to upgrade or downgrade the access of an * existing open (if it fails, the existing open prevails). * @param client * Client requesting the open. * @param options * Options for the open. Set to zero. * @param access * Access level for the open. Set to kIOStorageAccessReader or * kIOStorageAccessReaderWriter. * @result * Returns true if the open was successful, false otherwise. */ virtual bool open(IOService * client, IOOptionBits options, IOStorageAccess access); /*! * @function read * @discussion * Read data from the storage object at the specified byte offset into the * specified buffer, synchronously. When the read completes, this method * will return to the caller. The actual byte count field is optional. * @param client * Client requesting the read. * @param byteStart * Starting byte offset for the data transfer. * @param buffer * Buffer for the data transfer. The size of the buffer implies the size of * the data transfer. * @param attributes * Attributes of the data transfer. See IOStorageAttributes. * @param actualByteCount * Returns the actual number of bytes transferred in the data transfer. * @result * Returns the status of the data transfer. */ virtual IOReturn read(IOService * client, UInt64 byteStart, IOMemoryDescriptor * buffer, IOStorageAttributes * attributes = 0, UInt64 * actualByteCount = 0); /*! * @function write * @discussion * Write data into the storage object at the specified byte offset from the * specified buffer, synchronously. When the write completes, this method * will return to the caller. The actual byte count field is optional. * @param client * Client requesting the write. * @param byteStart * Starting byte offset for the data transfer. * @param buffer * Buffer for the data transfer. The size of the buffer implies the size of * the data transfer. * @param attributes * Attributes of the data transfer. See IOStorageAttributes. * @param actualByteCount * Returns the actual number of bytes transferred in the data transfer. * @result * Returns the status of the data transfer. */ virtual IOReturn write(IOService * client, UInt64 byteStart, IOMemoryDescriptor * buffer, IOStorageAttributes * attributes = 0, UInt64 * actualByteCount = 0); #if TARGET_OS_OSX virtual IOReturn synchronizeCache(IOService * client) __attribute__ ((deprecated)); #endif /* TARGET_OS_OSX */ /*! * @function read * @discussion * Read data from the storage object at the specified byte offset into the * specified buffer, asynchronously. When the read completes, the caller * will be notified via the specified completion action. * * The buffer will be retained for the duration of the read. * @param client * Client requesting the read. * @param byteStart * Starting byte offset for the data transfer. * @param buffer * Buffer for the data transfer. The size of the buffer implies the size of * the data transfer. * @param attributes * Attributes of the data transfer. See IOStorageAttributes. It is the * responsibility of the callee to maintain the information for the duration * of the data transfer, as necessary. * @param completion * Completion routine to call once the data transfer is complete. It is the * responsibility of the callee to maintain the information for the duration * of the data transfer, as necessary. */ virtual void read(IOService * client, UInt64 byteStart, IOMemoryDescriptor * buffer, IOStorageAttributes * attributes, IOStorageCompletion * completion) = 0; /*! * @function write * @discussion * Write data into the storage object at the specified byte offset from the * specified buffer, asynchronously. When the write completes, the caller * will be notified via the specified completion action. * * The buffer will be retained for the duration of the write. * @param client * Client requesting the write. * @param byteStart * Starting byte offset for the data transfer. * @param buffer * Buffer for the data transfer. The size of the buffer implies the size of * the data transfer. * @param attributes * Attributes of the data transfer. See IOStorageAttributes. It is the * responsibility of the callee to maintain the information for the duration * of the data transfer, as necessary. * @param completion * Completion routine to call once the data transfer is complete. It is the * responsibility of the callee to maintain the information for the duration * of the data transfer, as necessary. */ virtual void write(IOService * client, UInt64 byteStart, IOMemoryDescriptor * buffer, IOStorageAttributes * attributes, IOStorageCompletion * completion) = 0; #if TARGET_OS_OSX virtual IOReturn discard(IOService * client, UInt64 byteStart, UInt64 byteCount) __attribute__ ((deprecated)); #endif /* TARGET_OS_OSX */ /*! * @function unmap * @discussion * Delete unused data from the storage object at the specified byte offsets. * @param client * Client requesting the operation. * @param extents * List of extents. See IOStorageExtent. It is legal for the callee to * overwrite the contents of this buffer in order to satisfy the request. * @param extentsCount * Number of extents. * @param options * Options for the unmap. See IOStorageUnmapOptions. * @result * Returns the status of the operation. */ #if TARGET_OS_OSX virtual IOReturn unmap(IOService * client, IOStorageExtent * extents, UInt32 extentsCount, IOStorageUnmapOptions options = 0); /* 10.6.6 */ #else /* !TARGET_OS_OSX */ virtual IOReturn unmap(IOService * client, IOStorageExtent * extents, UInt32 extentsCount, IOStorageUnmapOptions options = 0) = 0; #endif /* !TARGET_OS_OSX */ /*! * @function lockPhysicalExtents * @discussion * Lock the contents of the storage object against relocation temporarily, * for the purpose of getting physical extents. * @param client * Client requesting the operation. * @result * Returns true if the lock was successful, false otherwise. */ virtual bool lockPhysicalExtents(IOService * client); /* 10.7.0 */ /*! * @function copyPhysicalExtent * @discussion * Convert the specified byte offset into a physical byte offset, relative * to a physical storage object. This call should only be made within the * context of lockPhysicalExtents(). * @param client * Client requesting the operation. * @param byteStart * Starting byte offset for the operation. Returns a physical byte offset, * relative to the physical storage object, on success. * @param byteCount * Size of the operation. Returns the actual number of bytes which can be * transferred, relative to the physical storage object, on success. * @result * A reference to the physical storage object, which should be released by * the caller, or a null on error. */ virtual IOStorage * copyPhysicalExtent(IOService * client, UInt64 * byteStart, UInt64 * byteCount); /* 10.7.0 */ /*! * @function unlockPhysicalExtents * @discussion * Unlock the contents of the storage object for relocation again. This * call must balance a successful call to lockPhysicalExtents(). * @param client * Client requesting the operation. */ virtual void unlockPhysicalExtents(IOService * client); /* 10.7.0 */ /*! * @function setPriority * @discussion * Reprioritize read or write requests at the specified byte offsets. * @param client * Client requesting the operation. * @param extents * List of extents. See IOStorageExtent. It is legal for the callee to * overwrite the contents of this buffer in order to satisfy the request. * @param extentsCount * Number of extents. * @param priority * New priority. See IOStoragePriority. * @result * Returns the status of the operation. */ virtual IOReturn setPriority(IOService * client, IOStorageExtent * extents, UInt32 extentsCount, IOStoragePriority priority); /* 10.10.0 */ /*! * @function synchronize * @discussion * Flush the cached data in the storage object, if any. * @param client * Client requesting the synchronization. * @param byteStart * Starting byte offset for the synchronization. * @param byteCount * Size of the synchronization. Set to zero to specify the end-of-media. * @param options * Options for the synchronization. See IOStorageSynchronizeOptions. * @result * Returns the status of the synchronization. */ #if TARGET_OS_OSX virtual IOReturn synchronize(IOService * client, UInt64 byteStart, UInt64 byteCount, IOStorageSynchronizeOptions options = 0); /* 10.11.0 */ #else /* !TARGET_OS_OSX */ virtual IOReturn synchronize(IOService * client, UInt64 byteStart, UInt64 byteCount, IOStorageSynchronizeOptions options = 0) = 0; #endif /* !TARGET_OS_OSX */ /*! * @function getProvisionStatus * @discussion * Get device block provision status * @param client * Client requesting the synchronization. * @param byteStart * Byte offset of logical extent on the device. * @param byteCount * Byte length of logical extent on the device, 0 mean the entire remaining space. * @param extentsCount * Number of extents allocated in extents. On return, this parameter indicate number * of provision extents returned. * @param extents * List of provision extents. See IOStorageProvisionExtents. * @param options * Options for get provision status. See IOStorageGetProvisionStatusOptions. * @result * Returns the status of the getProvisionStatus. */ virtual IOReturn getProvisionStatus(IOService * client, UInt64 byteStart, UInt64 byteCount, UInt32 * extentsCount, IOStorageProvisionExtent * extents, IOStorageGetProvisionStatusOptions options = 0 ); /* 10.12.0 */ OSMetaClassDeclareReservedUsed(IOStorage, 0); OSMetaClassDeclareReservedUsed(IOStorage, 1); OSMetaClassDeclareReservedUsed(IOStorage, 2); OSMetaClassDeclareReservedUsed(IOStorage, 3); OSMetaClassDeclareReservedUsed(IOStorage, 4); OSMetaClassDeclareReservedUsed(IOStorage, 5); OSMetaClassDeclareReservedUsed(IOStorage, 6); OSMetaClassDeclareReservedUnused(IOStorage, 7); OSMetaClassDeclareReservedUnused(IOStorage, 8); OSMetaClassDeclareReservedUnused(IOStorage, 9); OSMetaClassDeclareReservedUnused(IOStorage, 10); OSMetaClassDeclareReservedUnused(IOStorage, 11); OSMetaClassDeclareReservedUnused(IOStorage, 12); OSMetaClassDeclareReservedUnused(IOStorage, 13); OSMetaClassDeclareReservedUnused(IOStorage, 14); OSMetaClassDeclareReservedUnused(IOStorage, 15); }; #if TARGET_OS_OSX #ifdef KERNEL_PRIVATE #define _kIOStorageSynchronizeOption_super__synchronizeCache 0xFFFFFFFF #define _respondsTo_synchronizeCache ( IOStorage::_expansionData ) #endif /* KERNEL_PRIVATE */ #endif /* TARGET_OS_OSX */ #endif /* __cplusplus */ #endif /* KERNEL */ #endif /* !_IOSTORAGE_H */