#include <IOKit/assert.h>
#include <IOKit/IOLib.h>
#include <IOKit/IOSyncer.h>
#include <IOKit/storage/IOStorage.h>
#define super IOService
OSDefineMetaClassAndAbstractStructors(IOStorage, IOService)
#define kIOStorageAttributesUnsupported ( ( IOStorage::ExpansionData * ) 1 )
IOStorageAttributes gIOStorageAttributesUnsupported = { kIOStorageOptionReserved };
extern "C" void _ZN9IOStorage4readEP9IOServiceyP18IOMemoryDescriptor19IOStorageCompletion( IOStorage *, IOService *, UInt64, IOMemoryDescriptor *, IOStorageCompletion );
extern "C" void _ZN9IOStorage5writeEP9IOServiceyP18IOMemoryDescriptor19IOStorageCompletion( IOStorage *, IOService *, UInt64, IOMemoryDescriptor *, IOStorageCompletion );
extern "C" void _ZN9IOStorage4readEP9IOServiceyP18IOMemoryDescriptorP19IOStorageAttributesP19IOStorageCompletion( IOStorage *, IOService *, UInt64, IOMemoryDescriptor *, IOStorageAttributes *, IOStorageCompletion * );
extern "C" void _ZN9IOStorage5writeEP9IOServiceyP18IOMemoryDescriptorP19IOStorageAttributesP19IOStorageCompletion( IOStorage *, IOService *, UInt64, IOMemoryDescriptor *, IOStorageAttributes *, IOStorageCompletion * );
static bool storageAttributes( IOStorage * storage )
{
return ( OSMemberFunctionCast( void *, storage, ( void ( IOStorage::* )( IOService *, UInt64, IOMemoryDescriptor *, IOStorageCompletion ) ) &IOStorage::read ) == _ZN9IOStorage4readEP9IOServiceyP18IOMemoryDescriptor19IOStorageCompletion ) &&
( OSMemberFunctionCast( void *, storage, ( void ( IOStorage::* )( IOService *, UInt64, IOMemoryDescriptor *, IOStorageCompletion ) ) &IOStorage::write ) == _ZN9IOStorage5writeEP9IOServiceyP18IOMemoryDescriptor19IOStorageCompletion ) &&
( OSMemberFunctionCast( void *, storage, ( void ( IOStorage::* )( IOService *, UInt64, IOMemoryDescriptor *, IOStorageAttributes *, IOStorageCompletion * ) ) &IOStorage::read ) != _ZN9IOStorage4readEP9IOServiceyP18IOMemoryDescriptorP19IOStorageAttributesP19IOStorageCompletion ) &&
( OSMemberFunctionCast( void *, storage, ( void ( IOStorage::* )( IOService *, UInt64, IOMemoryDescriptor *, IOStorageAttributes *, IOStorageCompletion * ) ) &IOStorage::write ) != _ZN9IOStorage5writeEP9IOServiceyP18IOMemoryDescriptorP19IOStorageAttributesP19IOStorageCompletion );
}
static void storageCompletion(void * target,
void * parameter,
IOReturn status,
UInt64 actualByteCount)
{
if (parameter) *((UInt64 *)parameter) = actualByteCount;
((IOSyncer *)target)->signal(status);
}
bool IOStorage::init(OSDictionary * properties)
{
if ( super::init( properties ) == false )
{
return false;
}
if ( storageAttributes( this ) == false )
{
IOStorage::_expansionData = kIOStorageAttributesUnsupported;
}
if ( IOStorage::_expansionData )
{
OSDictionary * features;
features = OSDictionary::withCapacity( 1 );
if ( features )
{
setProperty( kIOStorageFeaturesKey, features );
features->release( );
}
}
return true;
}
void IOStorage::complete(IOStorageCompletion completion,
IOReturn status,
UInt64 actualByteCount)
{
complete( &completion, status, actualByteCount );
}
void IOStorage::complete(IOStorageCompletion * completion,
IOReturn status,
UInt64 actualByteCount)
{
if ( completion && completion->action )
{
( completion->action )( completion->target, completion->parameter, status, actualByteCount );
}
}
bool IOStorage::open(IOService * client,
IOOptionBits options,
IOStorageAccess access)
{
return super::open(client, options, (void *) access);
}
IOReturn IOStorage::read(IOService * client,
UInt64 byteStart,
IOMemoryDescriptor * buffer,
UInt64 * actualByteCount)
{
IOStorageCompletion completion;
IOSyncer * completionSyncer;
completionSyncer = IOSyncer::create();
completion.target = completionSyncer;
completion.action = storageCompletion;
completion.parameter = actualByteCount;
read(client, byteStart, buffer, completion);
return completionSyncer->wait();
}
IOReturn IOStorage::write(IOService * client,
UInt64 byteStart,
IOMemoryDescriptor * buffer,
UInt64 * actualByteCount)
{
IOStorageCompletion completion;
IOSyncer * completionSyncer;
completionSyncer = IOSyncer::create();
completion.target = completionSyncer;
completion.action = storageCompletion;
completion.parameter = actualByteCount;
write(client, byteStart, buffer, completion);
return completionSyncer->wait();
}
void IOStorage::read(IOService * client,
UInt64 byteStart,
IOMemoryDescriptor * buffer,
IOStorageCompletion completion)
{
if ( IOStorage::_expansionData == kIOStorageAttributesUnsupported )
{
read( client, byteStart, buffer, &gIOStorageAttributesUnsupported, &completion );
}
else
{
read( client, byteStart, buffer, NULL, &completion );
}
}
void IOStorage::write(IOService * client,
UInt64 byteStart,
IOMemoryDescriptor * buffer,
IOStorageCompletion completion)
{
if ( IOStorage::_expansionData == kIOStorageAttributesUnsupported )
{
write( client, byteStart, buffer, &gIOStorageAttributesUnsupported, &completion );
}
else
{
write( client, byteStart, buffer, NULL, &completion );
}
}
void IOStorage::read(IOService * client,
UInt64 byteStart,
IOMemoryDescriptor * buffer,
IOStorageAttributes * attributes,
IOStorageCompletion * completion)
{
if ( attributes && attributes->options )
{
complete( completion, kIOReturnUnsupported );
}
else
{
read( client, byteStart, buffer, completion ? *completion : ( IOStorageCompletion ) { 0 } );
}
}
OSMetaClassDefineReservedUsed(IOStorage, 0);
void IOStorage::write(IOService * client,
UInt64 byteStart,
IOMemoryDescriptor * buffer,
IOStorageAttributes * attributes,
IOStorageCompletion * completion)
{
if ( attributes && attributes->options )
{
complete( completion, kIOReturnUnsupported );
}
else
{
write( client, byteStart, buffer, completion ? *completion : ( IOStorageCompletion ) { 0 } );
}
}
OSMetaClassDefineReservedUsed(IOStorage, 1);
IOReturn IOStorage::discard(IOService * client,
UInt64 byteStart,
UInt64 byteCount)
{
return kIOReturnUnsupported;
}
OSMetaClassDefineReservedUsed(IOStorage, 2);
OSMetaClassDefineReservedUnused(IOStorage, 3);
OSMetaClassDefineReservedUnused(IOStorage, 4);
OSMetaClassDefineReservedUnused(IOStorage, 5);
OSMetaClassDefineReservedUnused(IOStorage, 6);
OSMetaClassDefineReservedUnused(IOStorage, 7);
OSMetaClassDefineReservedUnused(IOStorage, 8);
OSMetaClassDefineReservedUnused(IOStorage, 9);
OSMetaClassDefineReservedUnused(IOStorage, 10);
OSMetaClassDefineReservedUnused(IOStorage, 11);
OSMetaClassDefineReservedUnused(IOStorage, 12);
OSMetaClassDefineReservedUnused(IOStorage, 13);
OSMetaClassDefineReservedUnused(IOStorage, 14);
OSMetaClassDefineReservedUnused(IOStorage, 15);