darling-iostoragefamily/IOStorage.h
2022-12-03 19:04:00 -08:00

799 lines
27 KiB
C++

/*
* 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 <sys/kernel_types.h>
#include <IOKit/IOTypes.h>
/*!
* @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 <IOKit/assert.h>
#include <IOKit/IOMemoryDescriptor.h>
#include <IOKit/IOService.h>
/*!
* @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 */