AppleIntelICHxSATA.cpp [plain text]
#include<IOKit/storage/IOStorageProtocolCharacteristics.h>
#include "AppleIntelICHxSATA.h"
#define super AppleIntelPIIXPATA
OSDefineMetaClassAndStructors( AppleIntelICHxSATA, AppleIntelPIIXPATA )
bool AppleIntelICHxSATA::start( IOService * provider )
{
setProperty( kIOPropertyPhysicalInterconnectTypeKey,
kIOPropertyPhysicalInterconnectTypeSerialATA );
return super::start(provider);
}
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 );
UInt8 mask = 0;
switch ( port )
{
case kSerialATAPort0:
mask = kPIIX_PCI_PCS_P0E;
break;
case kSerialATAPort1:
mask = kPIIX_PCI_PCS_P1E;
break;
case kSerialATAPort2:
mask = kPIIX_PCI_PCS_P2E;
break;
case kSerialATAPort3:
mask = kPIIX_PCI_PCS_P3E;
break;
}
_provider->pciConfigWrite8( kPIIX_PCI_PCS,
enable ? mask : 0, mask );
}
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;
case kSerialATAPort2: mask = kPIIX_PCI_PCS_P2P; break;
case kSerialATAPort3: mask = kPIIX_PCI_PCS_P3P; break;
default: mask = 0;
}
return (( pcs & mask ) == mask);
}
IOReturn AppleIntelICHxSATA::selectDevice( ataUnitID unit )
{
if (_selectedUnit != kATADevice1DeviceID &&
_devInfo[0].type == kUnknownATADeviceType &&
_devInfo[1].type != kUnknownATADeviceType)
{
*_tfSDHReg = (1 << 4); }
return super::selectDevice( unit );
}
IOReturn AppleIntelICHxSATA::setPowerState( unsigned long stateIndex,
IOService * whatDevice )
{
if ( stateIndex == kPIIXPowerStateOff )
{
_initPortEnable = true;
}
else if ( _initPortEnable )
{
for ( UInt32 unit = 0; unit < _provider->getMaxDriveUnits(); unit++ )
{
setSATAPortEnable( unit,
_devInfo[unit].type != kUnknownATADeviceType );
}
_initPortEnable = false;
}
return super::setPowerState( stateIndex, whatDevice );
}
#if 0
static void dumpRegsICH6( IOPCIDevice * pci )
{
kprintf("INT_LN %x\n", pci->configRead8(0x3c));
kprintf("INT_PN %x\n", pci->configRead8(0x3d));
kprintf("IDE_TIMP %x\n", pci->configRead16(0x40));
kprintf("IDE_TIMS %x\n", pci->configRead16(0x42));
kprintf("IDE_SIDETIM %x\n", pci->configRead8(0x44));
kprintf("SDMA_CNT %x\n", pci->configRead8(0x48));
kprintf("SDMA_TIM %x\n", pci->configRead16(0x4a));
kprintf("IDE_CONFIG %x\n", pci->configRead32(0x54));
kprintf("PID %x\n", pci->configRead16(0x70));
kprintf("PC %x\n", pci->configRead16(0x72));
kprintf("PMCS %x\n", pci->configRead16(0x74));
kprintf("MAP %x\n", pci->configRead8(0x90));
kprintf("PCS %x\n", pci->configRead16(0x92));
kprintf("SIR %x\n", pci->configRead32(0x94));
kprintf("ATC %x\n", pci->configRead8(0xc0));
kprintf("ATS %x\n", pci->configRead8(0xc4));
kprintf("BFCS %x\n", pci->configRead32(0xe0));
pci->configWrite32(0xa0, 0);
kprintf("Index 0x00 %0x\n", pci->configRead32(0xa4));
pci->configWrite32(0xa0, 0x18);
kprintf("Index 0x18 %0x\n", pci->configRead32(0xa4));
pci->configWrite32(0xa0, 0x1c);
kprintf("Index 0x1c %0x\n", pci->configRead32(0xa4));
pci->configWrite32(0xa0, 0x28);
kprintf("Index 0x28 %0x\n", pci->configRead32(0xa4));
pci->configWrite32(0xa0, 0x54);
kprintf("Index 0x54 %0x\n", pci->configRead32(0xa4));
pci->configWrite32(0xa0, 0x64);
kprintf("Index 0x64 %0x\n", pci->configRead32(0xa4));
pci->configWrite32(0xa0, 0x74);
kprintf("Index 0x74 %0x\n", pci->configRead32(0xa4));
pci->configWrite32(0xa0, 0x84);
kprintf("Index 0x84 %0x\n", pci->configRead32(0xa4));
}
#endif