AppleGenericPCMultiATADriver.cpp [plain text]
#include <IOKit/IOLib.h>
#include "AppleGenericPCMultiATADriver.h"
#include "AppleGenericPCATAController.h"
#include "AppleGenericPCATAKeys.h"
#define super IOService
OSDefineMetaClassAndStructors( AppleGenericPCMultiATADriver, IOService )
bool
AppleGenericPCMultiATADriver::start( IOService * provider )
{
if ( super::start(provider) != true )
{
return false;
}
_provider = provider;
_provider->retain();
_nubs = createControllerNubs();
if ( _nubs == 0 )
{
return false;
}
_openNubs = OSSet::withCapacity( _nubs->getCount() );
if ( _openNubs == 0 )
{
return false;
}
return true;
}
void
AppleGenericPCMultiATADriver::free()
{
if ( _nubs )
{
_nubs->release();
_nubs = 0;
}
if ( _openNubs )
{
_openNubs->release();
_openNubs = 0;
}
if ( _provider )
{
_provider->release();
_provider = 0;
}
super::free();
}
OSSet *
AppleGenericPCMultiATADriver::createControllerNubs()
{
OSSet * nubSet;
OSArray * channels;
OSDictionary * channelInfo;
AppleGenericPCATAController * nub;
do {
nubSet = OSSet::withCapacity(4);
if ( nubSet == 0 )
break;
channels = OSDynamicCast( OSArray, getProperty( kATAChannelsKey ) );
if ( channels == 0 )
break;
for ( UInt32 i = 0; ; i++)
{
channelInfo = OSDynamicCast( OSDictionary, channels->getObject(i) );
if ( channelInfo == 0 )
break;
nub = new AppleGenericPCATAController;
if ( nub )
{
if ( nub->init( channelInfo ) &&
nub->attach( this ) &&
nubSet->setObject( nub ) )
{
nub->registerService();
}
nub->release();
}
}
}
while ( false );
if ( nubSet && (nubSet->getCount() == 0) )
{
nubSet->release();
nubSet = 0;
}
return nubSet;
}
bool
AppleGenericPCMultiATADriver::handleOpen( IOService * client,
IOOptionBits options,
void * arg )
{
bool ret = true;
if ( ( _nubs->containsObject( client ) == false ) ||
( _openNubs->containsObject( client ) == true ) )
return false;
if ( _openNubs->getCount() == 0 )
ret = _provider->open( this );
if ( ret )
{
_openNubs->setObject( client );
if ( arg ) *((IOService **) arg) = _provider;
}
return ret;
}
void
AppleGenericPCMultiATADriver::handleClose( IOService * client,
IOOptionBits options )
{
if ( _openNubs->containsObject( client ) == false ) return;
_openNubs->removeObject( client );
if ( _openNubs->getCount() == 0 )
_provider->close( this );
}
bool
AppleGenericPCMultiATADriver::handleIsOpen( const IOService * client ) const
{
if ( client )
return _openNubs->containsObject( client );
else
return ( _openNubs->getCount() != 0 );
}
#include <IOKit/pci/IOPCIDevice.h>
#undef super
#define super AppleGenericPCMultiATADriver
OSDefineMetaClassAndStructors( AppleGenericPCMultiPCIATADriver,
AppleGenericPCMultiATADriver )
IOService *
AppleGenericPCMultiPCIATADriver::probe( IOService * provider,
SInt32 * score )
{
IOPCIDevice * pciDevice;
if ( super::probe( provider, score ) == 0 )
return 0;
pciDevice = OSDynamicCast( IOPCIDevice, provider );
if ( pciDevice == 0 )
return 0;
if ( (pciDevice->configRead16( kIOPCIConfigCommand ) &
kIOPCICommandIOSpace) == 0 )
{
return 0;
}
return this;
}