AppleIntelICHxSATA.cpp [plain text]
#include "AppleIntelICHxSATA.h"
#define super AppleIntelPIIXPATA
OSDefineMetaClassAndStructors( AppleIntelICHxSATA, AppleIntelPIIXPATA )
IOReturn AppleIntelICHxSATA::provideBusInfo( IOATABusInfo * infoOut )
{
if ( super::provideBusInfo( infoOut ) != kATANoErr )
{
return -1;
}
infoOut->setSocketType( kInternalSATA );
return kATANoErr;
}
UInt32 AppleIntelICHxSATA::scanForDrives( void )
{
UInt32 unitsFound;
for ( int loopMs = 0; loopMs <= 3000; loopMs += 10 )
{
if ( (loopMs % 1000) == 0 )
{
for ( UInt32 i = 0; i < _provider->getMaxDriveUnits(); i++ )
setSATAPortEnable( i, false );
IOSleep( 20 );
for ( UInt32 i = 0; i < _provider->getMaxDriveUnits(); i++ )
setSATAPortEnable( i, true );
IOSleep( 20 );
*_tfAltSDevCReg = mATADCRReset;
IODelay( 100 );
*_tfAltSDevCReg = 0x0;
}
if ( (*_tfStatusCmdReg & mATABusy) == 0x00 )
break;
IOSleep( 10 );
}
unitsFound = IOPCIATA::scanForDrives();
for ( UInt32 unit = 0; unit < kMaxDrives; unit++ )
{
if ( _devInfo[unit].type != kUnknownATADeviceType &&
( unit >= _provider->getMaxDriveUnits() ||
getSATAPortPresentStatus( unit ) == false ) )
{
_devInfo[unit].type = kUnknownATADeviceType;
}
}
for ( UInt32 unit = 0; unit < _provider->getMaxDriveUnits(); unit++ )
{
if ( _devInfo[unit].type == kUnknownATADeviceType )
{
setSATAPortEnable( unit, false );
}
}
return unitsFound;
}
void AppleIntelICHxSATA::setSATAPortEnable( UInt32 driveUnit, bool enable )
{
int port = _provider->getSerialATAPortForDrive( driveUnit );
switch ( port )
{
case kSerialATAPort0:
_provider->pciConfigWrite8( kPIIX_PCI_PCS,
enable ? kPIIX_PCI_PCS_P0E : 0,
kPIIX_PCI_PCS_P0E );
break;
case kSerialATAPort1:
_provider->pciConfigWrite8( kPIIX_PCI_PCS,
enable ? kPIIX_PCI_PCS_P1E : 0,
kPIIX_PCI_PCS_P1E );
break;
}
}
bool AppleIntelICHxSATA::getSATAPortPresentStatus( UInt32 driveUnit )
{
int port = _provider->getSerialATAPortForDrive( driveUnit );
UInt8 pcs;
UInt8 mask;
pcs = _pciDevice->configRead8( kPIIX_PCI_PCS );
switch ( port )
{
case kSerialATAPort0: mask = kPIIX_PCI_PCS_P0P; break;
case kSerialATAPort1: mask = kPIIX_PCI_PCS_P1P; break;
default: mask = 0;
}
return (( pcs & mask ) == mask);
}