AppleIntelICHxSATA.cpp [plain text]
#include<IOKit/storage/IOStorageProtocolCharacteristics.h>
#include "AppleIntelICHxSATA.h"
#undef super
#define super IOPolledInterface
OSDefineMetaClassAndStructors( AppleIntelICHxSATAPolledAdapter, IOPolledInterface )
IOReturn
AppleIntelICHxSATAPolledAdapter::probe(IOService * target)
{
pollingActive = false;
return kIOReturnSuccess;
}
IOReturn
AppleIntelICHxSATAPolledAdapter::open( IOOptionBits state, IOMemoryDescriptor * buffer)
{
switch( state )
{
case kIOPolledPreflightState:
break;
case kIOPolledBeforeSleepState:
pollingActive = true;
break;
case kIOPolledAfterSleepState:
owner->transitionFixup();
pollingActive = true;
break;
case kIOPolledPostflightState:
default:
break;
}
return kIOReturnSuccess;
}
IOReturn
AppleIntelICHxSATAPolledAdapter::close(IOOptionBits state)
{
switch( state )
{
case kIOPolledPreflightState:
case kIOPolledBeforeSleepState:
case kIOPolledAfterSleepState:
case kIOPolledPostflightState:
default:
pollingActive = false;
break;
}
return kIOReturnSuccess;
}
IOReturn
AppleIntelICHxSATAPolledAdapter::startIO(uint32_t operation,
uint32_t bufferOffset,
uint64_t deviceOffset,
uint64_t length,
IOPolledCompletion completion)
{
return kIOReturnUnsupported;
}
IOReturn
AppleIntelICHxSATAPolledAdapter::checkForWork(void)
{
if( owner )
{
owner->pollEntry();
}
return kIOReturnSuccess;
}
bool
AppleIntelICHxSATAPolledAdapter::isPolling( void )
{
return pollingActive;
}
void
AppleIntelICHxSATAPolledAdapter::setOwner( AppleIntelICHxSATA* myOwner )
{
owner = myOwner;
pollingActive = false;
}
#undef super
#define super AppleIntelPIIXPATA
OSDefineMetaClassAndStructors( AppleIntelICHxSATA, AppleIntelPIIXPATA )
void
AppleIntelICHxSATA::pollEntry( void )
{
if( 0 == _currentCommand )
return;
if ( *(_bmStatusReg) & kPIIX_IO_BMISX_IDEINTS )
{
*(_bmStatusReg) = kPIIX_IO_BMISX_IDEINTS;
handleDeviceInterrupt();
}
}
void
AppleIntelICHxSATA::executeEventCallouts( ataEventCode event, ataUnitID unit )
{
if( polledAdapter && polledAdapter->isPolling())
{
return;
}
super::executeEventCallouts(event, unit);
}
IOReturn
AppleIntelICHxSATA::startTimer( UInt32 inMS)
{
if( polledAdapter && polledAdapter->isPolling())
{
return kIOReturnSuccess;
}
return super::startTimer( inMS);
}
void
AppleIntelICHxSATA::stopTimer(void)
{
if( polledAdapter && polledAdapter->isPolling())
{
return;
}
return super::stopTimer( );
}
void
AppleIntelICHxSATA::transitionFixup( void )
{
_queueState = IOATAController::kQueueOpen;
_busState = IOATAController::kBusFree;
_currentCommand = 0L;
_selectedUnit = kATAInvalidDeviceID;
_queueState = IOATAController::kQueueOpen;
_immediateGate = IOATAController::kImmediateOK;
_pciDevice->restoreDeviceState();
}
bool AppleIntelICHxSATA::start( IOService * provider )
{
setProperty( kIOPropertyPhysicalInterconnectTypeKey,
kIOPropertyPhysicalInterconnectTypeSerialATA );
polledAdapter = new AppleIntelICHxSATAPolledAdapter;
if( polledAdapter)
{
polledAdapter->setOwner( this );
setProperty ( kIOPolledInterfaceSupportKey, polledAdapter );
polledAdapter->release();
}
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++ )
_provider->setSerialATAPortEnableForDrive( i, false );
IOSleep( 20 );
for ( UInt32 i = 0; i < _provider->getMaxDriveUnits(); i++ )
_provider->setSerialATAPortEnableForDrive( 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() ||
_provider->getSerialATAPortPresentStatusForDrive( unit ) == false ) )
{
_devInfo[unit].type = kUnknownATADeviceType;
}
}
for ( UInt32 unit = 0; unit < _provider->getMaxDriveUnits(); unit++ )
{
if ( _devInfo[unit].type == kUnknownATADeviceType )
{
_provider->setSerialATAPortEnableForDrive( unit, false );
}
}
return unitsFound;
}
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++ )
{
_provider->setSerialATAPortEnableForDrive(
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