Example #1
0
OSSet * AppleIntelPIIXATARoot::createATAChannelNubs( void )
{
    OSSet *           nubSet;
    OSDictionary *    channelInfo;
    IORegistryEntry * dtEntry;
    UInt32            priChannelMode;
    UInt32            secChannelMode;
    UInt8             mapValue = 0;

    do {
        nubSet = OSSet::withCapacity(2);
        if ( nubSet == 0 )
            break;

        if ( _provider->open( this ) != true )
            break;

        priChannelMode = kChannelModePATA;
        secChannelMode = kChannelModePATA;

        // Determine SATA channel mode based on Port Mapping Register.

        if ( getProperty( kSerialATAKey ) == kOSBooleanTrue )
        {
            OSString * hwName;

            hwName = OSDynamicCast(OSString, getProperty(kControllerNameKey));
            mapValue = _provider->configRead8(kPIIX_PCI_MAP);
            setProperty( kPortMappingKey, mapValue, 8 );

            priChannelMode = kChannelModeDisabled;
            secChannelMode = kChannelModeDisabled;

            if (hwName)
            {
                if (hwName->isEqualTo("ICH7-M SATA"))
                {
                    mapValue &= 0x3;
                    priChannelMode = gICH7MChannelModeMap[mapValue][0];
                    secChannelMode = gICH7MChannelModeMap[mapValue][1];
                }
                else if (hwName->isEqualTo("ICH6 SATA") || hwName->isEqualTo("ESB2 SATA"))
                {
                    mapValue &= 0x3;
                    priChannelMode = gICH6ChannelModeMap[mapValue][0];
                    secChannelMode = gICH6ChannelModeMap[mapValue][1];
                }
                else if (hwName->isEqualTo("ICH6-M SATA"))
                {
                    mapValue &= 0x3;
                    priChannelMode = gICH6MChannelModeMap[mapValue][0];
                    secChannelMode = gICH6MChannelModeMap[mapValue][1];
                }
                else if (hwName->isEqualTo("ICH5 SATA"))
                {
                    mapValue &= 0x7;
                    priChannelMode = gICH5ChannelModeMap[mapValue][0];
                    secChannelMode = gICH5ChannelModeMap[mapValue][1];
                }
                else /* if (hwName->isEqualTo("ICH7 SATA")) */
                {
                    mapValue &= 0x3;
                    priChannelMode = gICH7ChannelModeMap[mapValue][0];
                    secChannelMode = gICH7ChannelModeMap[mapValue][1];
                }
            }
        }

        if ( priChannelMode == kChannelModeDisabled &&
             secChannelMode == kChannelModeDisabled )
        {
            IOLog("%s: bad value (%x) in Port Mapping register",
                  getName(), mapValue);
            _provider->close( this );
            break;
        }

        for ( UInt32 channelID = 0; channelID < 2; channelID++ )
        {
            UInt32 channelMode = (channelID ? secChannelMode : priChannelMode);

            // Create a dictionary for the channel info. Use native mode
            // settings if possible, else default to legacy mode.

            channelInfo = createNativeModeChannelInfo( channelID, channelMode );
            if (channelInfo == 0)
                channelInfo = createLegacyModeChannelInfo( channelID, channelMode );
            if (channelInfo == 0)
                continue;

            // Create a nub for each ATA channel.

            AppleIntelPIIXATAChannel * nub = new AppleIntelPIIXATAChannel;
            if ( nub )
            {
                dtEntry = getDTChannelEntry( channelID );

                if ( nub->init( this, channelInfo, dtEntry ) &&
                     nub->attach( this ) )
                {
                    nubSet->setObject( nub );
                }

                if ( dtEntry )
                {
                    dtEntry->release();
                }
                else
                {
                    // Platform did not create a device tree entry for
                    // this ATA channel. Do it here.

                    char channelName[5] = {'C','H','N','_','\0'};

                    channelName[3] = '0' + channelID;
                    nub->setName( channelName );

                    if ( _provider->inPlane(gIODTPlane) )
                    {
                        nub->attachToParent( _provider, gIODTPlane );
                    }
                }

                nub->release();
            }

            channelInfo->release();
        }
        
        _provider->close( this );
    }
    while ( false );

    // Release and invalidate an empty set.

    if ( nubSet && (nubSet->getCount() == 0) )
    {
        nubSet->release();
        nubSet = 0;
    }

    return nubSet;
}
OSSet * AppleNForceATARoot::createATAChannels( void )
{
    OSSet *           nubSet;
    OSDictionary *    channelInfo;
    IORegistryEntry * dtEntry;
	char* debugInfo;

    do {
        nubSet = OSSet::withCapacity(2);
        if (nubSet == 0)
            break;

        if (fProvider->open(this) != true)
            break;

        for ( UInt32 channelID = 0; channelID < 2; channelID++ )
        {        
            // Create a dictionary for the channel info. Use native mode
            // settings if possible, else default to legacy mode.

			debugInfo = "native";
            channelInfo = createNativeModeChannelInfo( channelID );
            if (channelInfo == 0) 
			{
				debugInfo = "legacy";
                channelInfo = createLegacyModeChannelInfo( channelID );
			}
            if (channelInfo == 0)
                continue;
				
			DEBUG_LOG( "%s::%s() [this=%p] created channel %d in %s mode.\n", 
				getName(), __FUNCTION__, this, (int)channelID, debugInfo );

            // Create a nub for each ATA channel.

            AppleNForceATAChannel * nub = new AppleNForceATAChannel;
            if ( nub )
            {
                dtEntry = getDTChannelEntry( channelID );

                // Invoke special init method in channel nub.

                if (nub->init( this, channelInfo, dtEntry ) &&
                    nub->attach( this ))
                {
                    nubSet->setObject( nub );
                }

                if ( dtEntry )
                {
                    dtEntry->release();
                }
                else
                {
                    // Platform did not create a device tree entry for
                    // this ATA channel. Do it here.

                    char channelName[5] = {'C','H','N','_','\0'};

                    channelName[3] = '0' + channelID;
                    nub->setName( channelName );

                    if (fProvider->inPlane(gIODTPlane))
                    {
                        nub->attachToParent( fProvider, gIODTPlane );
                    }
                }

                nub->release();
            }

            channelInfo->release();
        }
        
        fProvider->close( this );
    }
    while ( false );

    // Release and invalidate an empty set.

    if (nubSet && (nubSet->getCount() == 0))
    {
        nubSet->release();
        nubSet = 0;
    }

    return nubSet;
}