␊ |
typedef UInt32 IOMediaState;␊ |
␊ |
#ifdef KERNEL␊ |
#ifdef __cplusplus␊ |
␊ |
/*␊ |
* Kernel␊ |
*/␊ |
␊ |
#include <IOKit/storage/IOBlockStorageDevice.h>␊ |
#include <IOKit/storage/IOMedia.h>␊ |
#include <IOKit/storage/IOStorage.h>␊ |
#include <kern/thread_call.h>␊ |
␊ |
/*!␊ |
* @class IOBlockStorageDriver␊ |
* @abstract␊ |
* The common base class for generic block storage drivers.␊ |
* @discussion␊ |
* The IOBlockStorageDriver class is the common base class for generic block␊ |
* storage drivers. It matches and communicates via an IOBlockStorageDevice␊ |
* interface, and connects to the remainder of the storage framework via the␊ |
* IOStorage protocol. It extends the IOStorage protocol by implementing the␊ |
* appropriate open and close semantics, deblocking for unaligned transfers,␊ |
* polling for ejectable media, locking and ejection policies, media object␊ |
* creation and tear-down, and statistics gathering and reporting.␊ |
*␊ |
* Block storage drivers are split into two parts: the generic driver handles␊ |
* all generic device issues, independent of the lower-level transport␊ |
* mechanism (e.g. SCSI, ATA, USB, FireWire). All storage operations␊ |
* at the generic driver level are translated into a series of generic␊ |
* device operations. These operations are passed via the IOBlockStorageDevice␊ |
* nub to a transport driver, which implements the appropriate␊ |
* transport-dependent protocol to execute these operations.␊ |
*␊ |
* To determine the write-protect state of a device (or media), for␊ |
* example, the generic driver would issue a call to the␊ |
* Transport Driver's reportWriteProtection method. If this were a SCSI␊ |
* device, its transport driver would issue a Mode Sense command to␊ |
* extract the write-protection status bit. The transport driver then␊ |
* reports true or false to the generic driver.␊ |
* ␊ |
* The generic driver therefore has no knowledge of, or involvement␊ |
* with, the actual commands and mechanisms used to communicate with␊ |
* the device. It is expected that the generic driver will rarely, if␊ |
* ever, need to be subclassed to handle device idiosyncrasies; rather,␊ |
* the transport driver should be changed via overrides.␊ |
* ␊ |
* A generic driver could be subclassed to create a different type of␊ |
* generic device. The generic driver IOCDBlockStorageDriver class is␊ |
* a subclass of IOBlockStorageDriver, adding CD functions.␊ |
*/␊ |
␊ |
class IOBlockStorageDriver : public IOStorage␊ |
{␊ |
OSDeclareDefaultStructors(IOBlockStorageDriver);␊ |
␊ |
public:␊ |
␊ |
/*!␊ |
* @enum Statistics␊ |
* @abstract␊ |
* Indices for the different statistics that getStatistics() can report.␊ |
* @constant kStatisticsReads Number of read operations thus far.␊ |
* @constant kStatisticsBytesRead Number of bytes read thus far.␊ |
* @constant kStatisticsTotalReadTime Nanoseconds spent performing reads thus far.␊ |
* @constant kStatisticsLatentReadTime Nanoseconds of latency during reads thus far.␊ |
* @constant kStatisticsReadRetries Number of read retries thus far.␊ |
* @constant kStatisticsReadErrors Number of read errors thus far.␊ |
* @constant kStatisticsWrites Number of write operations thus far.␊ |
* @constant kStatisticsSingleBlockWrites Number of write operations for a single block thus far.␊ |
* @constant kStatisticsBytesWritten Number of bytes written thus far.␊ |
* @constant kStatisticsTotalWriteTime Nanoseconds spent performing writes thus far.␊ |
* @constant kStatisticsLatentWriteTime Nanoseconds of latency during writes thus far.␊ |
* @constant kStatisticsWriteRetries Number of write retries thus far.␊ |
* @constant kStatisticsWriteErrors Number of write errors thus far.␊ |
*/␊ |
␊ |
enum Statistics␊ |
{␊ |
kStatisticsReads,␊ |
kStatisticsBytesRead,␊ |
kStatisticsTotalReadTime,␊ |
kStatisticsLatentReadTime,␊ |
kStatisticsReadRetries,␊ |
kStatisticsReadErrors,␊ |
␊ |
kStatisticsWrites,␊ |
kStatisticsSingleBlockWrites,␊ |
kStatisticsBytesWritten,␊ |
kStatisticsTotalWriteTime,␊ |
kStatisticsLatentWriteTime,␊ |
kStatisticsWriteRetries,␊ |
kStatisticsWriteErrors␊ |
};␊ |
␊ |
static const UInt32 kStatisticsCount = kStatisticsWriteErrors + 1;␊ |
␊ |
protected:␊ |
␊ |
struct Context;␊ |
␊ |
struct ExpansionData␊ |
{␊ |
bool mediaDirtied;␊ |
UInt64 maxReadBlockTransfer;␊ |
UInt64 maxWriteBlockTransfer;␊ |
IONotifier * powerEventNotifier;␊ |
UInt32 deblockRequestWriteLockCount;␊ |
UInt64 maxReadSegmentTransfer;␊ |
UInt64 maxWriteSegmentTransfer;␊ |
UInt64 maxReadSegmentByteTransfer;␊ |
UInt64 maxWriteSegmentByteTransfer;␊ |
UInt64 minSegmentAlignmentByteTransfer;␊ |
UInt64 maxSegmentWidthByteTransfer;␊ |
Context * contexts;␊ |
IOSimpleLock * contextsLock;␊ |
UInt32 contextsCount;␊ |
UInt32 contextsMaxCount;␊ |
};␊ |
ExpansionData * _expansionData;␊ |
␊ |
#define _mediaDirtied \␊ |
IOBlockStorageDriver::_expansionData->mediaDirtied␊ |
#define _maxReadBlockTransfer \␊ |
IOBlockStorageDriver::_expansionData->maxReadBlockTransfer␊ |
#define _maxWriteBlockTransfer \␊ |
IOBlockStorageDriver::_expansionData->maxWriteBlockTransfer␊ |
#define _powerEventNotifier \␊ |
IOBlockStorageDriver::_expansionData->powerEventNotifier␊ |
#define _deblockRequestWriteLockCount \␊ |
IOBlockStorageDriver::_expansionData->deblockRequestWriteLockCount␊ |
#define _maxReadSegmentTransfer \␊ |
IOBlockStorageDriver::_expansionData->maxReadSegmentTransfer␊ |
#define _maxWriteSegmentTransfer \␊ |
IOBlockStorageDriver::_expansionData->maxWriteSegmentTransfer␊ |
#define _maxReadSegmentByteTransfer \␊ |
IOBlockStorageDriver::_expansionData->maxReadSegmentByteTransfer␊ |
#define _maxWriteSegmentByteTransfer \␊ |
IOBlockStorageDriver::_expansionData->maxWriteSegmentByteTransfer␊ |
#define _minSegmentAlignmentByteTransfer \␊ |
IOBlockStorageDriver::_expansionData->minSegmentAlignmentByteTransfer␊ |
#define _maxSegmentWidthByteTransfer \␊ |
IOBlockStorageDriver::_expansionData->maxSegmentWidthByteTransfer␊ |
#define _contexts \␊ |
IOBlockStorageDriver::_expansionData->contexts␊ |
#define _contextsLock \␊ |
IOBlockStorageDriver::_expansionData->contextsLock␊ |
#define _contextsCount \␊ |
IOBlockStorageDriver::_expansionData->contextsCount␊ |
#define _contextsMaxCount \␊ |
IOBlockStorageDriver::_expansionData->contextsMaxCount␊ |
␊ |
OSSet * _openClients;␊ |
OSNumber * _statistics[kStatisticsCount];␊ |
␊ |
/*␊ |
* @struct Context␊ |
* @discussion␊ |
* Context structure for a read/write operation. It describes the block size,␊ |
* and where applicable, a block type and block sub-type, for a data transfer,␊ |
* as well as the completion information for the original request. Note that␊ |
* the block type field is unused in the IOBlockStorageDriver class.␊ |
* @field block.size␊ |
* Block size for the operation.␊ |
* @field block.type␊ |
* Block type for the operation. Unused in IOBlockStorageDriver. The default␊ |
* value for this field is IOBlockStorageDriver::kBlockTypeStandard.␊ |
* @field block.typeSub␊ |
* Block sub-type for the operation. It's definition depends on block.type.␊ |
* Unused in IOBlockStorageDriver.␊ |
* @field request.byteStart␊ |
* Starting byte offset for the data transfer.␊ |
* @param request.buffer␊ |
* Buffer for the data transfer. The size of the buffer implies the size of␊ |
* the data transfer.␊ |
* @param request.attributes␊ |
* Attributes of the data transfer. See IOStorageAttributes.␊ |
* @param request.completion␊ |
* Completion routine to call once the data transfer is complete.␊ |
*/␊ |
␊ |
struct Context␊ |
{␊ |
#ifdef __LP64__␊ |
struct␊ |
{␊ |
UInt64 byteStart;␊ |
IOMemoryDescriptor * buffer;␊ |
IOStorageAttributes attributes;␊ |
IOStorageCompletion completion;␊ |
} request;␊ |
␊ |
struct␊ |
{␊ |
UInt32 size;␊ |
UInt8 type;␊ |
UInt8 typeSub[3];␊ |
} block;␊ |
␊ |
AbsoluteTime timeStart;␊ |
␊ |
UInt64 reserved0704;␊ |
UInt64 reserved0768;␊ |
UInt64 reserved0832;␊ |
UInt64 reserved0896;␊ |
#else /* !__LP64__ */␊ |
struct␊ |
{␊ |
UInt32 size;␊ |
UInt8 type;␊ |
UInt8 typeSub[3];␊ |
} block;␊ |
␊ |
struct␊ |
{␊ |
UInt64 byteStart;␊ |
IOMemoryDescriptor * buffer;␊ |
IOStorageCompletion completion;␊ |
} original;␊ |
␊ |
AbsoluteTime timeStart;␊ |
␊ |
struct␊ |
{␊ |
IOStorageAttributes attributes;␊ |
} request;␊ |
␊ |
UInt32 reserved0448;␊ |
#endif /* !__LP64__ */␊ |
␊ |
Context * next;␊ |
};␊ |
␊ |
static const UInt8 kBlockTypeStandard = 0x00;␊ |
␊ |
/*␊ |
* Free all of this object's outstanding resources.␊ |
*␊ |
* This method's implementation is not typically overridden.␊ |
*/␊ |
␊ |
void free();␊ |
␊ |
/*!␊ |
* @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.␊ |
*␊ |
* This implementation replaces the IOService definition of handleIsOpen().␊ |
* @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);␊ |
␊ |
/*!␊ |
* @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.␊ |
*␊ |
* This implementation replaces the IOService definition of handleIsOpen().␊ |
* @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;␊ |
␊ |
/*!␊ |
* @function handleClose␊ |
* @discussion␊ |
* The handleClose method closes the client's access to this object.␊ |
*␊ |
* This implementation replaces the IOService definition of handleIsOpen().␊ |
* @param client␊ |
* Client requesting the close.␊ |
* @param options␊ |
* Options for the close. Set to zero.␊ |
*/␊ |
␊ |
virtual void handleClose(IOService * client, IOOptionBits options);␊ |
␊ |
/*!␊ |
* @function addToBytesTransferred␊ |
* @discussion␊ |
* Update the total number of bytes transferred, the total transfer time,␊ |
* and the total latency time -- used for statistics.␊ |
*␊ |
* This method's implementation is not typically overridden.␊ |
* @param bytesTransferred␊ |
* Number of bytes transferred in this operation.␊ |
* @param totalTime␊ |
* Nanoseconds spent performing this operation.␊ |
* @param latentTime␊ |
* Nanoseconds of latency during this operation.␊ |
* @param isWrite␊ |
* Indicates whether this operation was a write, otherwise is was a read.␊ |
*/␊ |
␊ |
virtual void addToBytesTransferred(UInt64 bytesTransferred,␊ |
UInt64 totalTime,␊ |
UInt64 latentTime,␊ |
bool isWrite);␊ |
␊ |
/*!␊ |
* @function incrementErrors␊ |
* @discussion␊ |
* Update the total error count -- used for statistics.␊ |
*␊ |
* This method's implementation is not typically overridden.␊ |
* @param isWrite␊ |
* Indicates whether this operation was a write, otherwise is was a read.␊ |
*/␊ |
␊ |
virtual void incrementErrors(bool isWrite);␊ |
␊ |
/*!␊ |
* @function incrementRetries␊ |
* @discussion␊ |
* Update the total retry count -- used for statistics.␊ |
*␊ |
* This method's implementation is not typically overridden.␊ |
* @param isWrite␊ |
* Indicates whether this operation was a write, otherwise is was a read.␊ |
*/␊ |
␊ |
virtual void incrementRetries(bool isWrite);␊ |
␊ |
/*!␊ |
* @function allocateContext␊ |
* @discussion␊ |
* Allocate a context structure for a read/write operation.␊ |
* @result␊ |
* Context structure.␊ |
*/␊ |
␊ |
virtual Context * allocateContext();␊ |
␊ |
/*!␊ |
* @function deleteContext␊ |
* @discussion␊ |
* Delete a context structure from a read/write operation.␊ |
* @param context␊ |
* Context structure to be deleted.␊ |
*/␊ |
␊ |
virtual void deleteContext(Context * context);␊ |
␊ |
#ifndef __LP64__␊ |
virtual void prepareRequest(UInt64 byteStart,␊ |
IOMemoryDescriptor * buffer,␊ |
IOStorageCompletion completion) __attribute__ ((deprecated));␊ |
#endif /* !__LP64__ */␊ |
␊ |
/*!␊ |
* @function deblockRequest␊ |
* @discussion␊ |
* The deblockRequest method checks to see if the incoming request rests␊ |
* on the media's block boundaries, and if not, deblocks it. Deblocking␊ |
* involves rounding out the request to the nearest block boundaries and␊ |
* transferring the excess bytes into a scratch buffer.␊ |
*␊ |
* This method is part of a sequence of methods invoked for each read/write␊ |
* request. The first is prepareRequest, which allocates and prepares some␊ |
* context for the transfer; the second is deblockRequest, which aligns the␊ |
* transfer at the media's block boundaries; third is breakUpRequest, which␊ |
* breaks up the transfer into multiple sub-transfers when certain hardware␊ |
* constraints are exceeded; fourth is executeRequest, which implements the␊ |
* actual transfer from the block storage device.␊ |
*␊ |
* This method's implementation is not typically overridden.␊ |
* @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.␊ |
* @param context␊ |
* Additional context information for the data transfer (e.g. block size).␊ |
*/␊ |
␊ |
#ifdef __LP64__␊ |
virtual void deblockRequest(UInt64 byteStart,␊ |
IOMemoryDescriptor * buffer,␊ |
IOStorageAttributes * attributes,␊ |
IOStorageCompletion * completion,␊ |
Context * context);␊ |
#else /* !__LP64__ */␊ |
virtual void deblockRequest(UInt64 byteStart,␊ |
IOMemoryDescriptor * buffer,␊ |
IOStorageCompletion completion,␊ |
Context * context);␊ |
#endif /* !__LP64__ */␊ |
␊ |
/*!␊ |
* @function executeRequest␊ |
* @discussion␊ |
* Execute an asynchronous storage request. The request is guaranteed to be␊ |
* block-aligned.␊ |
*␊ |
* This method is part of a sequence of methods invoked for each read/write␊ |
* request. The first is prepareRequest, which allocates and prepares some␊ |
* context for the transfer; the second is deblockRequest, which aligns the␊ |
* transfer at the media's block boundaries; third is breakUpRequest, which␊ |
* breaks up the transfer into multiple sub-transfers when certain hardware␊ |
* constraints are exceeded; fourth is executeRequest, which implements the␊ |
* actual transfer from the block storage device.␊ |
* @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.␊ |
* @param context␊ |
* Additional context information for the data transfer (e.g. block size).␊ |
*/␊ |
␊ |
#ifdef __LP64__␊ |
virtual void executeRequest(UInt64 byteStart,␊ |
IOMemoryDescriptor * buffer,␊ |
IOStorageAttributes * attributes,␊ |
IOStorageCompletion * completion,␊ |
Context * context);␊ |
#else /* !__LP64__ */␊ |
virtual void executeRequest(UInt64 byteStart,␊ |
IOMemoryDescriptor * buffer,␊ |
IOStorageCompletion completion,␊ |
Context * context);␊ |
#endif /* !__LP64__ */␊ |
␊ |
/*!␊ |
* @function handleStart␊ |
* @discussion␊ |
* Prepare the block storage driver for operation.␊ |
*␊ |
* This is where a media object needs to be created for fixed media, and␊ |
* optionally for removable media.␊ |
*␊ |
* Note that this method is called from within the start() routine;␊ |
* if this method returns successfully, it should be prepared to accept␊ |
* any of IOBlockStorageDriver's APIs.␊ |
* @param provider␊ |
* This object's provider.␊ |
* @result␊ |
* Returns true on success, false otherwise.␊ |
*/␊ |
␊ |
virtual bool handleStart(IOService * provider);␊ |
␊ |
/*!␊ |
* @function handleYield␊ |
* @discussion␊ |
* Stop the block storage driver.␊ |
*␊ |
* This method is called as a result of a kIOMessageServiceIsRequestingClose␊ |
* provider message. The argument is passed in as-is from the message. The␊ |
* options are unused.␊ |
*␊ |
* This is where the driver should clean up its state in preparation for␊ |
* removal from the system.␊ |
*␊ |
* Note that this method is called from within the yield() routine.␊ |
*␊ |
* This method is called with the arbitration lock held.␊ |
* @param provider␊ |
* This object's provider.␊ |
*/␊ |
␊ |
virtual bool handleYield(IOService * provider,␊ |
IOOptionBits options = 0,␊ |
void * argument = 0);␊ |
␊ |
␊ |
/*!␊ |
* @function getMediaBlockSize␊ |
* @discussion␊ |
* Ask the driver about the media's natural block size.␊ |
* @result␊ |
* Natural block size, in bytes.␊ |
*/␊ |
␊ |
virtual UInt64 getMediaBlockSize() const;␊ |
␊ |
public:␊ |
␊ |
using IOStorage::read;␊ |
using IOStorage::write;␊ |
␊ |
/*␊ |
* Initialize this object's minimal state.␊ |
*␊ |
* This method's implementation is not typically overridden.␊ |
*/␊ |
␊ |
virtual bool init(OSDictionary * properties = 0);␊ |
␊ |
/*␊ |
* This method is called once we have been attached to the provider object.␊ |
*␊ |
* This method's implementation is not typically overridden.␊ |
*/␊ |
␊ |
virtual bool start(IOService * provider);␊ |
␊ |
/*␊ |
* This method is called before we are detached from the provider object.␊ |
*␊ |
* This method's implementation is not typically overridden.␊ |
*/␊ |
␊ |
virtual void stop(IOService * provider);␊ |
␊ |
/*␊ |
* This method is called as a result of a kIOMessageServiceIsRequestingClose␊ |
* provider message. The argument is passed in as-is from the message. The␊ |
* options are unused.␊ |
*␊ |
* This method's implementation is not typically overridden.␊ |
*/␊ |
␊ |
virtual bool yield(IOService * provider,␊ |
IOOptionBits options = 0,␊ |
void * argument = 0);␊ |
␊ |
/*!␊ |
* @function read␊ |
* @discussion␊ |
* The read method is the receiving end for all read requests from the␊ |
* storage framework (through the media object created by this driver).␊ |
*␊ |
* This method initiates a sequence of methods (stages) for each read/write␊ |
* request. The first is prepareRequest, which allocates and prepares some␊ |
* context for the transfer; the second is deblockRequest, which aligns the␊ |
* transfer at the media's block boundaries; third is breakUpRequest, which␊ |
* breaks up the transfer into multiple sub-transfers when certain hardware␊ |
* constraints are exceeded; fourth is executeRequest, which implements the␊ |
* actual transfer from the block storage device.␊ |
*␊ |
* This method's implementation is not typically overridden.␊ |
* @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);␊ |
␊ |
/*!␊ |
* @function write␊ |
* @discussion␊ |
* The write method is the receiving end for all write requests from the␊ |
* storage framework (through the media object created by this driver).␊ |
*␊ |
* This method initiates a sequence of methods (stages) for each read/write␊ |
* request. The first is prepareRequest, which allocates and prepares some␊ |
* context for the transfer; the second is deblockRequest, which aligns the␊ |
* transfer at the media's block boundaries; third is breakUpRequest, which␊ |
* breaks up the transfer into multiple sub-transfers when certain hardware␊ |
* constraints are exceeded; fourth is executeRequest, which implements the␊ |
* actual transfer from the block storage device.␊ |
*␊ |
* This method's implementation is not typically overridden.␊ |
* @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);␊ |
␊ |
/*!␊ |
* @function synchronizeCache␊ |
* @discussion␊ |
* Flush the cached data in the storage object, if any, synchronously.␊ |
* @param client␊ |
* Client requesting the cache synchronization.␊ |
* @result␊ |
* Returns the status of the cache synchronization.␊ |
*/␊ |
␊ |
virtual IOReturn synchronizeCache(IOService * client);␊ |
␊ |
/*!␊ |
* @function discard␊ |
* @discussion␊ |
* Delete unused data from the storage object at the specified byte offset,␊ |
* synchronously.␊ |
* @param client␊ |
* Client requesting the operation.␊ |
* @param byteStart␊ |
* Starting byte offset for the operation.␊ |
* @param byteCount␊ |
* Size of the operation.␊ |
* @result␊ |
* Returns the status of the operation.␊ |
*/␊ |
␊ |
virtual IOReturn discard(IOService * client,␊ |
UInt64 byteStart,␊ |
UInt64 byteCount);␊ |
␊ |
/*!␊ |
* @function ejectMedia␊ |
* @discussion␊ |
* Eject the media from the device. The driver is responsible for tearing␊ |
* down the media object it created before proceeding with the eject. If␊ |
* the tear-down fails, an error should be returned.␊ |
* @result␊ |
* An IOReturn code.␊ |
*/␊ |
␊ |
virtual IOReturn ejectMedia();␊ |
␊ |
/*!␊ |
* @function formatMedia␊ |
* @discussion␊ |
* Format the media with the specified byte capacity. The driver is␊ |
* responsible for tearing down the media object and recreating it.␊ |
* @param byteCapacity␊ |
* Number of bytes to format media to.␊ |
* @result␊ |
* An IOReturn code.␊ |
*/␊ |
␊ |
virtual IOReturn formatMedia(UInt64 byteCapacity);␊ |
␊ |
/*!␊ |
* @function lockMedia␊ |
* @discussion␊ |
* Lock or unlock the ejectable media in the device, that is, prevent␊ |
* it from manual ejection or allow its manual ejection.␊ |
* @param lock␊ |
* Pass true to lock the media, otherwise pass false to unlock the media.␊ |
* @result␊ |
* An IOReturn code.␊ |
*/␊ |
␊ |
virtual IOReturn lockMedia(bool lock);␊ |
␊ |
/*!␊ |
* @function pollMedia␊ |
* @discussion␊ |
* Poll for the presence of media in the device. The driver is responsible␊ |
* for tearing down the media object it created should the media have been␊ |
* removed since the last poll, and vice-versa, creating the media object␊ |
* should new media have arrived since the last poll.␊ |
* @result␊ |
* An IOReturn code.␊ |
*/␊ |
␊ |
virtual IOReturn pollMedia();␊ |
␊ |
/*!␊ |
* @function isMediaEjectable␊ |
* @discussion␊ |
* Ask the driver whether the media is ejectable.␊ |
* @result␊ |
* Returns true if the media is ejectable, false otherwise.␊ |
*/␊ |
␊ |
virtual bool isMediaEjectable() const;␊ |
␊ |
#ifdef __LP64__␊ |
/*!␊ |
* @function isMediaRemovable␊ |
* @discussion␊ |
* Ask the driver whether the media is ejectable.␊ |
* @result␊ |
* Returns true if the media is ejectable, false otherwise.␊ |
*/␊ |
␊ |
virtual bool isMediaRemovable() const;␊ |
#endif /* __LP64__ */␊ |
␊ |
/*!␊ |
* @function isMediaPollExpensive␊ |
* @discussion␊ |
* Ask the driver whether a pollMedia() would be an expensive operation,␊ |
* that is, one that requires the device to spin up or delay for a while.␊ |
* @result␊ |
* Returns true if polling the media is expensive, false otherwise.␊ |
*/␊ |
␊ |
virtual bool isMediaPollExpensive() const;␊ |
␊ |
/*!␊ |
* @function isMediaPollRequired␊ |
* @discussion␊ |
* Ask the driver whether the block storage device requires polling, which is␊ |
* typically required for devices without the ability to asynchronously detect␊ |
* the arrival or departure of the media.␊ |
* @result␊ |
* Returns true if polling the media is required, false otherwise.␊ |
*/␊ |
␊ |
virtual bool isMediaPollRequired() const;␊ |
␊ |
virtual bool isMediaWritable() const;␊ |
␊ |
/*!␊ |
* @function getMediaState␊ |
* @discussion␊ |
* Ask the driver about the media's current state.␊ |
* @result␊ |
* An IOMediaState value.␊ |
*/␊ |
␊ |
virtual IOMediaState getMediaState() const;␊ |
␊ |
/*!␊ |
* @function getFormatCapacities␊ |
* @discussion␊ |
* Ask the driver to report the feasible formatting capacities for the␊ |
* inserted media (in bytes). This routine fills the caller's buffer,␊ |
* up to the maximum count specified if the real number of capacities␊ |
* would overflow the buffer. The return value indicates the actual␊ |
* number of capacities copied to the buffer.␊ |
*␊ |
* If the capacities buffer is not supplied or if the maximum count is␊ |
* zero, the routine returns the proposed count of capacities instead.␊ |
* @param capacities␊ |
* Buffer that will receive the UInt64 capacity values.␊ |
* @param capacitiesMaxCount␊ |
* Maximum number of capacity values that can be held in the buffer.␊ |
* @result␊ |
* Actual number of capacity values copied to the buffer, or if no buffer␊ |
* is given, the total number of capacity values available.␊ |
*/␊ |
␊ |
virtual UInt32 getFormatCapacities(UInt64 * capacities,␊ |
UInt32 capacitiesMaxCount) const;␊ |
␊ |
/*!␊ |
* @function getStatistics␊ |
* @discussion␊ |
* Ask the driver to report its operating statistics.␊ |
*␊ |
* The statistics are each indexed by IOBlockStorageDriver::Statistics␊ |
* indices. This routine fills the caller's buffer, up to the maximum␊ |
* count specified if the real number of statistics would overflow the␊ |
* buffer. The return value indicates the actual number of statistics␊ |
* copied to the buffer.␊ |
*␊ |
* If the statistics buffer is not supplied or if the maximum count is␊ |
* zero, the routine returns the proposed count of statistics instead.␊ |
* @param statistics␊ |
* Buffer that will receive the UInt64 statistic values.␊ |
* @param statisticsMaxCount␊ |
* Maximum number of statistic values that can be held in the buffer.␊ |
* @result␊ |
* Actual number of statistic values copied to the buffer, or if no buffer␊ |
* is given, the total number of statistic values available.␊ |
*/␊ |
␊ |
virtual UInt32 getStatistics(UInt64 * statistics,␊ |
UInt32 statisticsMaxCount) const;␊ |
␊ |
/*!␊ |
* @function getStatistic␊ |
* @discussion␊ |
* Ask the driver to report one of its operating statistics.␊ |
* @param statistic␊ |
* Statistic index (an IOBlockStorageDriver::Statistics index).␊ |
* @result␊ |
* Statistic value.␊ |
*/␊ |
␊ |
virtual UInt64 getStatistic(Statistics statistic) const;␊ |
␊ |
/*␊ |
* Generic entry point for calls from the provider. A return value of␊ |
* kIOReturnSuccess indicates that the message was received, and where␊ |
* applicable, that it was successful.␊ |
*/␊ |
␊ |
virtual IOReturn message(UInt32 type, IOService * provider, void * argument);␊ |
␊ |
/*␊ |
* Obtain this object's provider. We override the superclass's method to␊ |
* return a more specific subclass of IOService -- IOBlockStorageDevice. ␊ |
* This method serves simply as a convenience to subclass developers.␊ |
*/␊ |
␊ |
virtual IOBlockStorageDevice * getProvider() const;␊ |
␊ |
protected:␊ |
␊ |
IOLock * _deblockRequestWriteLock;␊ |
thread_call_t _pollerCall;␊ |
␊ |
/*␊ |
* This is the completion routine for the broken up breaker sub-requests.␊ |
* It verifies the success of the just-completed stage, transitions to␊ |
* the next stage, then builds and issues a transfer for the next stage.␊ |
*/␊ |
␊ |
static void breakUpRequestCompletion(void * target,␊ |
void * parameter,␊ |
IOReturn status,␊ |
UInt64 actualByteCount);␊ |
␊ |
/*␊ |
* This is the completion routine for the aligned deblocker sub-requests.␊ |
* It verifies the success of the just-completed stage, transitions to␊ |
* the next stage, then builds and issues a transfer for the next stage.␊ |
*/␊ |
␊ |
static void deblockRequestCompletion(void * target,␊ |
void * parameter,␊ |
IOReturn status,␊ |
UInt64 actualByteCount);␊ |
␊ |
/*␊ |
* This is the completion routine for the prepared request. It updates␊ |
* the driver's statistics, performs some clean up work, then calls the␊ |
* original request's completion routine.␊ |
*/␊ |
␊ |
static void prepareRequestCompletion(void * target,␊ |
void * parameter,␊ |
IOReturn status,␊ |
UInt64 actualByteCount);␊ |
␊ |
/*␊ |
* Schedule the poller mechanism.␊ |
*/␊ |
␊ |
virtual void schedulePoller();␊ |
␊ |
/*␊ |
* Unschedule the poller mechanism.␊ |
*/␊ |
␊ |
virtual void unschedulePoller();␊ |
␊ |
/*␊ |
* This method is the timeout handler for the poller mechanism. It polls␊ |
* for media and reschedules another timeout if there are still no opens.␊ |
*/␊ |
␊ |
static void poller(void *, void *);␊ |
␊ |
/*␊ |
* This method is the power event handler for restarts and shutdowns.␊ |
*/␊ |
␊ |
static IOReturn handlePowerEvent(void * target,␊ |
void * parameter,␊ |
UInt32 messageType,␊ |
IOService * provider,␊ |
void * messageArgument,␊ |
vm_size_t messageArgumentSize);␊ |
␊ |
protected:␊ |
␊ |
/* Device info: */␊ |
␊ |
/*!␊ |
* @var _removable␊ |
* True if the media is removable; False if it is fixed (not removable).␊ |
*/␊ |
bool␉␉_removable;␊ |
␊ |
/*!␊ |
* @var _ejectable␊ |
* True if the media is ejectable under software control.␊ |
*/␊ |
bool␉␉_ejectable;␉␉/* software-ejectable */␊ |
␊ |
/*!␊ |
* @var _lockable␊ |
* True if the media can be locked in the device under software control.␊ |
*/␊ |
bool␉␉_lockable;␉␉/* software lockable in device */␊ |
/*!␊ |
* @var _pollIsRequired␊ |
* True if we must poll to detect media insertion or removal.␊ |
*/␊ |
bool␉␉_pollIsRequired;␊ |
/*!␊ |
* @var _pollIsExpensive␊ |
* True if polling is expensive; False if not.␊ |
*/␊ |
bool␉␉_pollIsExpensive;␊ |
␊ |
/* Media info and states: */␊ |
␊ |
/*!␊ |
* @var _mediaObject␊ |
* A pointer to the media object we have instantiated (if any).␊ |
*/␊ |
IOMedia *␉␉_mediaObject;␊ |
/*!␊ |
* @var _mediaType␊ |
* Type of the media (can be used to differentiate between the␊ |
* different types of CD media, DVD media, etc).␊ |
*/␊ |
UInt32␉␉_mediaType;␊ |
/*!␊ |
* @var _mediaPresent␊ |
* True if media is present in the device; False if not.␊ |
*/␊ |
bool␉␉_mediaPresent;␉␉/* media is present and ready */␊ |
/*!␊ |
* @var _writeProtected␊ |
* True if the media is write-protected; False if not.␊ |
*/␊ |
bool␉␉_writeProtected;␊ |
␊ |
private:␊ |
␊ |
/*!␊ |
* @var _mediaStateLock␊ |
* A lock used to protect during media checks.␊ |
*/␊ |
IOLock *␉␉_mediaStateLock;␊ |
␊ |
protected:␊ |
␊ |
/*!␊ |
* @var _mediaBlockSize␊ |
* The block size of the media, in bytes.␊ |
*/␊ |
UInt64␉␉_mediaBlockSize;␊ |
/*!␊ |
* @var _maxBlockNumber␊ |
* The maximum allowable block number for the media, zero-based.␊ |
*/␊ |
UInt64␉␉_maxBlockNumber;␊ |
␊ |
/*!␊ |
* @var _maxReadByteTransfer␊ |
* The maximum byte transfer allowed for read operations.␊ |
*/␊ |
UInt64␉␉_maxReadByteTransfer;␊ |
␊ |
/*!␊ |
* @var _maxWriteByteTransfer␊ |
* The maximum byte transfer allowed for write operations.␊ |
*/␊ |
UInt64␉␉_maxWriteByteTransfer;␊ |
␊ |
/*!␊ |
* @function acceptNewMedia␊ |
* @abstract␊ |
* React to new media insertion.␊ |
* @discussion␊ |
* This method logs the media block size and block count, then calls␊ |
* instantiateMediaObject to get a media object instantiated. The␊ |
* media object is then attached above us and registered.␊ |
* ␊ |
* This method can be overridden to control what happens when new media␊ |
* is inserted. The default implementation deals with one IOMedia object.␊ |
*/␊ |
virtual IOReturn␉acceptNewMedia(void);␊ |
␊ |
/*!␊ |
* @function constrainByteCount␊ |
* @abstract␊ |
* Constrain the byte count for this IO to device limits.␊ |
* @discussion␊ |
* This function should be called prior to each read or write operation, so that␊ |
* the driver can constrain the requested byte count, as necessary, to meet␊ |
* current device limits. Such limits could be imposed by the device depending␊ |
* on operating modes, media types, or transport protocol (e.g. ATA, SCSI).␊ |
* ␊ |
* At present, this method is not used.␊ |
* @param requestedCount␊ |
* The requested byte count for the next read or write operation.␊ |
* @param isWrite␊ |
* True if the operation will be a write; False if the operation will be a read.␊ |
*/␊ |
virtual UInt64␉constrainByteCount(UInt64 requestedCount,bool isWrite);␊ |
␊ |
/*!␊ |
* @function decommissionMedia␊ |
* @abstract␊ |
* Decommission an existing piece of media that has gone away.␊ |
* @discussion␊ |
* This method wraps a call to terminate, to tear down the stack and␊ |
* the IOMedia object for the media. If "forcible" is true, the media␊ |
* object will be forgotten, and initMediaState will be called. A␊ |
* forcible decommission would occur when an unrecoverable error␊ |
* happens during tear-down (e.g. perhaps a client is still open), but␊ |
* we must still forget about the media.␊ |
* @param forcible␊ |
* True to force forgetting of the media object even if terminate reports␊ |
* that there was an active client.␊ |
*/␊ |
virtual IOReturn␉decommissionMedia(bool forcible);␊ |
␊ |
/*!␊ |
* @function instantiateDesiredMediaObject␊ |
* @abstract␊ |
* Create an IOMedia object for media.␊ |
* @discussion␊ |
* This method creates the exact type of IOMedia object desired. It is called by␊ |
* instantiateMediaObject. A subclass may override this one-line method to change␊ |
* the type of media object actually instantiated.␊ |
*/␊ |
virtual IOMedia *␉instantiateDesiredMediaObject(void);␊ |
␊ |
/*!␊ |
* @function instantiateMediaObject␊ |
* @abstract␊ |
* Create an IOMedia object for media.␊ |
* @discussion␊ |
* This method creates an IOMedia object from the supplied parameters. It is a␊ |
* convenience method to wrap the handful of steps to do the job.␊ |
* @param base␊ |
* Byte number of beginning of active data area of the media. Usually zero.␊ |
* @param byteSize␊ |
* Size of the data area of the media, in bytes.␊ |
* @param blockSize␊ |
* Block size of the media, in bytes.␊ |
* @param mediaName␊ |
* Name of the IOMedia object.␊ |
* @result␊ |
* A pointer to the created IOMedia object, or a null on error.␊ |
*/␊ |
virtual IOMedia *␉instantiateMediaObject(UInt64 base,UInt64 byteSize,␊ |
UInt32 blockSize,char *mediaName);␊ |
␊ |
/*!␊ |
* @function recordMediaParameters␊ |
* @abstract␊ |
* Obtain media-related parameters on media insertion.␊ |
* @discussion␊ |
* This method obtains media-related parameters via calls to the␊ |
* Transport Driver's reportBlockSize, reportMaxValidBlock,␊ |
* and reportWriteProtection methods.␊ |
*/␊ |
virtual IOReturn␉recordMediaParameters(void);␊ |
␊ |
/*!␊ |
* @function rejectMedia␊ |
* @abstract␊ |
* Reject new media.␊ |
* @discussion␊ |
* This method will be called if validateNewMedia returns False (thus rejecting␊ |
* the new media. A vendor may choose to override this method to control behavior␊ |
* when media is rejected.␊ |
* ␊ |
* The default implementation simply calls ejectMedia.␊ |
*/␊ |
virtual void␉rejectMedia(void);␉/* default ejects */␊ |
␊ |
/*!␊ |
* @function validateNewMedia␊ |
* @abstract␊ |
* Verify that new media is acceptable.␊ |
* @discussion␊ |
* This method will be called whenever new media is detected. Return true to accept␊ |
* the media, or false to reject it (and call rejectMedia). Vendors might override␊ |
* this method to handle password-protection for new media.␊ |
* ␊ |
* The default implementation always returns True, indicating media is accepted.␊ |
*/␊ |
virtual bool␉validateNewMedia(void);␊ |
␊ |
/* --- Internally used methods. --- */␊ |
␊ |
/*␊ |
* @group␊ |
* Internally Used Methods␊ |
* @discussion␊ |
* These methods are used internally, and will not generally be modified.␊ |
*/␊ |
␊ |
/*!␊ |
* @function checkForMedia␊ |
* @abstract␊ |
* Check if media has newly arrived or disappeared.␊ |
* @discussion␊ |
* This method does most of the work in polling for media, first␊ |
* calling the block storage device's reportMediaState method. If␊ |
* reportMediaState reports no change in the media state, kIOReturnSuccess␊ |
* is returned. If the media state has indeed changed, a call is made to␊ |
* mediaStateHasChanged to act on the event.␊ |
*/␊ |
virtual IOReturn␉checkForMedia(void);␊ |
␊ |
/*!␊ |
* @function getDeviceTypeName␊ |
* @abstract␊ |
* Return the desired device name.␊ |
* @discussion␊ |
* This method returns a string, used to compare the ␊ |
* kIOBlockStorageDeviceTypeKey of our provider. This method is called from␊ |
* probe.␊ |
* ␊ |
* The default implementation of this method returns ␊ |
* kIOBlockStorageDeviceTypeGeneric.␊ |
*/␊ |
virtual const char * getDeviceTypeName(void);␊ |
␊ |
/*!␊ |
* @function initMediaState␊ |
* @abstract␊ |
* Initialize media-related instance variables.␊ |
* @discussion␊ |
* Called when media is not present, this method marks the device state␊ |
* as not having media present, not spun up, and write-enabled.␊ |
*/␊ |
virtual void␉initMediaState(void);␊ |
␊ |
/*!␊ |
* @function mediaStateHasChanged␊ |
* @abstract␊ |
* React to a new media insertion or a media removal.␊ |
* @discussion␊ |
* This method is called on a media state change, that is, an arrival␊ |
* or removal. If media has just become available, calls are made to␊ |
* recordMediaParameters and acceptNewMedia. If media has just gone␊ |
* away, a call is made to decommissionMedia, with the forcible␊ |
* parameter set to true. The forcible tear-down is needed to enforce␊ |
* the disappearance of media, regardless of interested clients.␊ |
*/␊ |
virtual IOReturn␉mediaStateHasChanged(IOMediaState state);␊ |
␊ |
/*␊ |
* @endgroup␊ |
*/␊ |
␊ |
protected:␊ |
␊ |
/*!␊ |
* @function breakUpRequest␊ |
* @discussion␊ |
* The breakUpRequest method checks to see if the incoming request exceeds␊ |
* our transfer constraints, and if so, breaks up the request into smaller␊ |
* sub-requests.␊ |
*␊ |
* This method is part of a sequence of methods invoked for each read/write␊ |
* request. The first is prepareRequest, which allocates and prepares some␊ |
* context for the transfer; the second is deblockRequest, which aligns the␊ |
* transfer at the media's block boundaries; third is breakUpRequest, which␊ |
* breaks up the transfer into multiple sub-transfers when certain hardware␊ |
* constraints are exceeded; fourth is executeRequest, which implements the␊ |
* actual transfer from the block storage device.␊ |
*␊ |
* This method's implementation is not typically overridden.␊ |
* @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.␊ |
* @param context␊ |
* Additional context information for the data transfer (e.g. block size).␊ |
*/␊ |
␊ |
#ifdef __LP64__␊ |
virtual void breakUpRequest(UInt64 byteStart,␊ |
IOMemoryDescriptor * buffer,␊ |
IOStorageAttributes * attributes,␊ |
IOStorageCompletion * completion,␊ |
Context * context);␊ |
#else /* !__LP64__ */␊ |
virtual void breakUpRequest(UInt64 byteStart,␊ |
IOMemoryDescriptor * buffer,␊ |
IOStorageCompletion completion,␊ |
Context * context); /* 10.1.2 */␊ |
#endif /* !__LP64__ */␊ |
␊ |
/*!␊ |
* @function prepareRequest␊ |
* @discussion␊ |
* The prepareRequest method allocates and prepares state for the transfer.␊ |
*␊ |
* This method is part of a sequence of methods invoked for each read/write␊ |
* request. The first is prepareRequest, which allocates and prepares some␊ |
* context for the transfer; the second is deblockRequest, which aligns the␊ |
* transfer at the media's block boundaries; third is breakUpRequest, which␊ |
* breaks up the transfer into multiple sub-transfers when certain hardware␊ |
* constraints are exceeded; fourth is executeRequest, which implements the␊ |
* actual transfer from the block storage device.␊ |
*␊ |
* This method's implementation is not typically overridden.␊ |
* @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 prepareRequest(UInt64 byteStart,␊ |
IOMemoryDescriptor * buffer,␊ |
IOStorageAttributes * attributes,␊ |
IOStorageCompletion * completion); /* 10.5.0 */␊ |
␊ |
public:␊ |
␊ |
/*!␊ |
* @function requestIdle␊ |
* @abstract␊ |
* Request that the device enter an idle state.␊ |
* @discussion␊ |
* Request that the device enter an idle state. The device will exit this state on the␊ |
* next read or write request, or as it sees necessary. One example is for a DVD drive␊ |
* to spin down when it enters such an idle state, and spin up on the next read request␊ |
* from the system.␊ |
*/␊ |
virtual IOReturn␉requestIdle(void); /* 10.6.0 */␊ |
␊ |
#ifdef __LP64__␊ |
OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 0);␊ |
OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 1);␊ |
OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 2);␊ |
#else /* !__LP64__ */␊ |
OSMetaClassDeclareReservedUsed(IOBlockStorageDriver, 0);␊ |
OSMetaClassDeclareReservedUsed(IOBlockStorageDriver, 1);␊ |
OSMetaClassDeclareReservedUsed(IOBlockStorageDriver, 2);␊ |
#endif /* !__LP64__ */␊ |
OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 3);␊ |
OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 4);␊ |
OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 5);␊ |
OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 6);␊ |
OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 7);␊ |
OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 8);␊ |
OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 9);␊ |
OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 10);␊ |
OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 11);␊ |
OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 12);␊ |
OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 13);␊ |
OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 14);␊ |
OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 15);␊ |
OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 16);␊ |
OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 17);␊ |
OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 18);␊ |
OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 19);␊ |
OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 20);␊ |
OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 21);␊ |
OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 22);␊ |
OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 23);␊ |
OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 24);␊ |
OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 25);␊ |
OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 26);␊ |
OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 27);␊ |
OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 28);␊ |
OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 29);␊ |
OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 30);␊ |
OSMetaClassDeclareReservedUnused(IOBlockStorageDriver, 31);␊ |
};␊ |
␊ |
#endif /* __cplusplus */␊ |
#endif /* KERNEL */␊ |
#endif /* !_IOBLOCKSTORAGEDRIVER_H */␊ |