IOATADevConfig.cpp [plain text]
const int configword = 00;
const int pioModeNumber = 51;
const int fieldValidity = 53;
const int mwDMAWord = 63;
const int pioAdvancedMode = 64;
const int minimumDMATime = 65;
const int recommendDMATime = 66;
const int pioCycleNoFlow = 67;
const int pioCycleIORDY = 68;
const int ultraDMAWord = 88;
#include<IOKit/IOTypes.h>
#include"IOATATypes.h"
#include"IOATADevConfig.h"
#include"IOATABusInfo.h"
#ifdef DLOG
#undef DLOG
#endif
#ifdef ATA_DEBUG
#define DLOG(fmt, args...) IOLog(fmt, ## args)
#else
#define DLOG(fmt, args...)
#endif
#define super OSObject
OSDefineMetaClassAndStructors ( IOATADevConfig, OSObject )
OSMetaClassDefineReservedUnused(IOATADevConfig, 0);
OSMetaClassDefineReservedUnused(IOATADevConfig, 1);
OSMetaClassDefineReservedUnused(IOATADevConfig, 2);
OSMetaClassDefineReservedUnused(IOATADevConfig, 3);
OSMetaClassDefineReservedUnused(IOATADevConfig, 4);
OSMetaClassDefineReservedUnused(IOATADevConfig, 5);
OSMetaClassDefineReservedUnused(IOATADevConfig, 6);
OSMetaClassDefineReservedUnused(IOATADevConfig, 7);
OSMetaClassDefineReservedUnused(IOATADevConfig, 8);
OSMetaClassDefineReservedUnused(IOATADevConfig, 9);
OSMetaClassDefineReservedUnused(IOATADevConfig, 10);
OSMetaClassDefineReservedUnused(IOATADevConfig, 11);
OSMetaClassDefineReservedUnused(IOATADevConfig, 12);
OSMetaClassDefineReservedUnused(IOATADevConfig, 13);
OSMetaClassDefineReservedUnused(IOATADevConfig, 14);
OSMetaClassDefineReservedUnused(IOATADevConfig, 15);
OSMetaClassDefineReservedUnused(IOATADevConfig, 16);
OSMetaClassDefineReservedUnused(IOATADevConfig, 17);
OSMetaClassDefineReservedUnused(IOATADevConfig, 18);
OSMetaClassDefineReservedUnused(IOATADevConfig, 19);
OSMetaClassDefineReservedUnused(IOATADevConfig, 20);
IOATADevConfig*
IOATADevConfig::atadevconfig(void)
{
IOATADevConfig* config = new IOATADevConfig;
if( !config )
return 0L;
if( !config->init() )
{
return 0L;
}
return config;
}
bool
IOATADevConfig::init( )
{
if( ! super::init() )
return false;
_atapiIRQForPacket = kATAPIUnknown;
_ataPIOMode = 0x00;
_ataPIOCycleTime = 0;
_ataMultiDMAMode = 0x00;
_ataMultiCycleTime = 0;
_ataUltraDMAMode = 0x00;
return true;
}
IOReturn
IOATADevConfig::initWithBestSelection( const UInt16* identifyData, IOATABusInfo* busInfo)
{
IOReturn err = kATANoErr;
err = assignFromData( identifyData );
if( err )
return err;
_ataPIOMode = _ataPIOMode & busInfo->getPIOModes();
_ataMultiDMAMode = _ataMultiDMAMode & busInfo->getDMAModes();
_ataUltraDMAMode = _ataUltraDMAMode & busInfo->getUltraModes();
if( _ataUltraDMAMode != 0x00 )
{
_ataMultiDMAMode = 0x00;
}
_ataPIOMode = _MostSignificantBit(_ataPIOMode);
_ataMultiDMAMode = _MostSignificantBit(_ataMultiDMAMode);
_ataUltraDMAMode = _MostSignificantBit(_ataUltraDMAMode);
return kATANoErr;
}
IOReturn
IOATADevConfig::assignFromData( const UInt16* identifyData )
{
if ( ( identifyData[0] & 0xC000 ) == 0xC000 )
{
return kATAErrUnknownType;
}
if( ( identifyData[0] & 0x8000 ) )
{
_atapiIRQForPacket = ( atapiConfig )( ( identifyData[0] & 0x0060 ) >> 5 );
}
_AssignPIOData ( identifyData );
_AssignDMAData ( identifyData );
_AssignUltraData ( identifyData );
return kATANoErr;
}
IOReturn
IOATADevConfig::_AssignPIOData( const UInt16* identifyData)
{
UInt16 advancedPIO = 0x0000;
_ataPIOCycleTime = 0;
_ataPIOMode = 0;
if( 0x0002 & identifyData[fieldValidity] )
{
advancedPIO = (identifyData[ pioAdvancedMode ] & 0x03) << 3 ;
if(advancedPIO != 0x0000)
{
_ataPIOCycleTime = identifyData[ pioCycleIORDY ];
if( _ataPIOCycleTime == 0 )
{
_ataPIOCycleTime = 180;
}
_ataPIOMode = advancedPIO | 0x0007;
return kATANoErr;
}
}
switch( identifyData[ pioModeNumber] & 0xFF00 )
{
case 0x0200:
_ataPIOMode = 0x07; _ataPIOCycleTime = 240;
break;
case 0x0100:
_ataPIOMode = 0x03; _ataPIOCycleTime = 383;
break;
default:
_ataPIOMode = 0x01; _ataPIOCycleTime = 600;
break;
}
return kATANoErr;
}
IOReturn
IOATADevConfig::_AssignDMAData(const UInt16* identifyData)
{
_ataMultiDMAMode = 0;
_ataMultiCycleTime = 0;
if( 0x0002 & identifyData[fieldValidity] )
{
_ataMultiDMAMode = identifyData[mwDMAWord] & 0x0007;
if( identifyData[recommendDMATime] > identifyData[minimumDMATime] )
{
_ataMultiCycleTime = identifyData[recommendDMATime];
} else {
_ataMultiCycleTime = identifyData[minimumDMATime];
}
}
return kATANoErr;
}
IOReturn
IOATADevConfig::_AssignUltraData(const UInt16* identifyData)
{
_ataUltraDMAMode = 0;
if( 0x0004 & identifyData[fieldValidity] )
{
_ataUltraDMAMode = identifyData[ultraDMAWord] & 0x00FF;
}
return kATANoErr;
}
void
IOATADevConfig::setPacketConfig ( atapiConfig packetConfig)
{
_atapiIRQForPacket = packetConfig;
}
atapiConfig
IOATADevConfig::getPacketConfig( void )
{
return _atapiIRQForPacket;
}
void
IOATADevConfig::setPIOMode( UInt8 inModeBitMap)
{
_ataPIOMode = inModeBitMap;
}
UInt8
IOATADevConfig::getPIOMode( void )
{
return _ataPIOMode;
}
void
IOATADevConfig::setDMAMode( UInt8 inModeBitMap )
{
_ataMultiDMAMode = inModeBitMap;
}
UInt8
IOATADevConfig::getDMAMode( void )
{
return _ataMultiDMAMode;
}
void
IOATADevConfig::setUltraMode( UInt8 inModeBitMap )
{
_ataUltraDMAMode = inModeBitMap;
}
UInt8
IOATADevConfig::getUltraMode( void )
{
return _ataUltraDMAMode;
}
void
IOATADevConfig::setPIOCycleTime( UInt16 inNS )
{
_ataPIOCycleTime = inNS;
}
UInt16
IOATADevConfig::getPIOCycleTime( void )
{
return _ataPIOCycleTime;
}
void
IOATADevConfig::setDMACycleTime( UInt16 inNS )
{
_ataMultiCycleTime = inNS;
}
UInt16
IOATADevConfig::getDMACycleTime( void )
{
return _ataMultiCycleTime;
}
UInt8
IOATADevConfig::_MostSignificantBit( UInt8 inByte)
{
if( inByte == 0)
return inByte;
UInt8 mask = 0x80;
for( int i = 7; i >0; i--)
{
if( mask & inByte )
{
return mask;
}
mask >>= 1;
}
return 0x01;
}
UInt8
IOATADevConfig::bitSigToNumeric(UInt16 binary)
{
UInt16 i, integer;
for (i = 0x0080, integer = 7; ((i & binary) == 0 && i != 0) ; i >>= 1, integer-- )
{;}
return (integer);
}
bool
IOATADevConfig::sDriveSupports48BitLBA( const UInt16* identifyData )
{
if( (identifyData[83] & 0x0400)
&& (identifyData[86] & 0x0400))
{
return true;
}
return false;
}
UInt32
IOATADevConfig::sDriveExtendedLBASize( UInt32* lbaHi, UInt32* lbaLo, const UInt16* identifyData)
{
UInt32 lowerLBA = 0;
UInt32 upperLBA = 0;
if( IOATADevConfig::sDriveSupports48BitLBA( identifyData ) )
{
lowerLBA = identifyData[ 100 ] | ( identifyData[101] << 16 );
upperLBA = identifyData[102] | ( identifyData[103] << 16 );
}
*lbaLo = lowerLBA;
*lbaHi = upperLBA;
return lowerLBA;
}