OSDictionary *
AppleIntelPIIXATARoot::createLegacyModeChannelInfo( UInt32 ataChannel,
                                                    UInt32 channelMode )
{
    UInt16  cmdPort = 0;
    UInt16  ctrPort = 0;
    UInt8   irq = 0;

    switch ( ataChannel )
    {
        case kPIIX_CHANNEL_PRIMARY:
            cmdPort = kPIIX_P_CMD_ADDR;
            ctrPort = kPIIX_P_CTL_ADDR;
            irq     = kPIIX_P_IRQ;
            break;
        
        case kPIIX_CHANNEL_SECONDARY:
            cmdPort = kPIIX_S_CMD_ADDR;
            ctrPort = kPIIX_S_CTL_ADDR;
            irq     = kPIIX_S_IRQ;
            break;
    }

    return createChannelInfo( ataChannel, channelMode,
                              cmdPort, ctrPort, irq );
}
OSDictionary *
AppleIntelPIIXATARoot::createNativeModeChannelInfo( UInt32 ataChannel,
                                                    UInt32 channelMode )
{
    UInt8  pi = _provider->configRead8( kPIIX_PCI_PI );
    UInt16 cmdPort = 0;
    UInt16 ctrPort = 0;

    switch ( ataChannel )
    {
        case kPIIX_CHANNEL_PRIMARY:
            if ((pi & kPIIX_PCI_PRI_NATIVE_MASK) == kPIIX_PCI_PRI_NATIVE_MASK)
            {
                // Primary channel native mode supported and enabled.

                cmdPort = _provider->configRead16( kIOPCIConfigBaseAddress0 );
                ctrPort = _provider->configRead16( kIOPCIConfigBaseAddress1 );
                
                cmdPort &= ~0x1;  // clear PCI I/O space indicator bit
                ctrPort &= ~0x1;
                
                // Programming interface byte indicate that native mode
                // is supported and active, but the controller has been
                // assigned legacy ranges. Force legacy mode configuration
                // which is safest. PCI INT# interrupts are not wired
                // properly for some machines in this state.

                if ( cmdPort == kPIIX_P_CMD_ADDR &&
                     ctrPort == kPIIX_P_CTL_ADDR )
                {
                     cmdPort = ctrPort = 0;
                }
            }
            break;

        case kPIIX_CHANNEL_SECONDARY:
            if ((pi & kPIIX_PCI_SEC_NATIVE_MASK) == kPIIX_PCI_SEC_NATIVE_MASK)
            {
                cmdPort = _provider->configRead16( kIOPCIConfigBaseAddress2 );
                ctrPort = _provider->configRead16( kIOPCIConfigBaseAddress3 );

                cmdPort &= ~0x1;  // clear PCI I/O space indicator bit
                ctrPort &= ~0x1;

                if ( cmdPort == kPIIX_S_CMD_ADDR &&
                     ctrPort == kPIIX_S_CTL_ADDR )
                {
                     cmdPort = ctrPort = 0;
                }
            }
            break;
    }

    if ( cmdPort && ctrPort )
        return createChannelInfo( ataChannel, channelMode, cmdPort, ctrPort,
                     _provider->configRead8( kIOPCIConfigInterruptLine ) );
    else
        return 0;
}
OSDictionary *
AppleNForceATARoot::createNativeModeChannelInfo( UInt32 ataChannel )
{
    UInt8  pi = fProvider->configRead8( PCI_PI );
    UInt16 cmdPort = 0;
    UInt16 ctrPort = 0;

    // Force native mode configuration for SATA.

    //if (fIsSATA) pi = 0xFF;

    switch ( ataChannel )
    {
        case PRI_CHANNEL_ID:
            if ( pi & 0x3 )
            {
                cmdPort = fProvider->configRead16( kIOPCIConfigBaseAddress0 );
                ctrPort = fProvider->configRead16( kIOPCIConfigBaseAddress1 );
                cmdPort &= ~0x1;  // clear PCI I/O space indicator bit
                ctrPort &= ~0x1;

                // Programming interface byte indicate that native mode
                // is supported and active, but the controller has been
                // assigned legacy ranges. Force legacy mode configuration
                // which is safest. PCI INT# interrupts are not wired
                // properly for some machines in this state.

                if ( cmdPort == PRI_CMD_ADDR &&
                     ctrPort == PRI_CTR_ADDR )
                {
                     cmdPort = ctrPort = 0;
                }
            }
            break;

        case SEC_CHANNEL_ID:
            if ( pi & 0xc )
            {
                cmdPort = fProvider->configRead16( kIOPCIConfigBaseAddress2 );
                ctrPort = fProvider->configRead16( kIOPCIConfigBaseAddress3 );
                cmdPort &= ~0x1;  // clear PCI I/O space indicator bit
                ctrPort &= ~0x1;

                if ( cmdPort == SEC_CMD_ADDR &&
                     ctrPort == SEC_CTR_ADDR )
                {
                     cmdPort = ctrPort = 0;
                }
            }
            break;
    }

    if (cmdPort && ctrPort)
        return createChannelInfo( ataChannel, cmdPort, ctrPort,
                     fProvider->configRead8(kIOPCIConfigInterruptLine) );
    else
        return 0;
}
OSDictionary *
AppleNForceATARoot::createLegacyModeChannelInfo( UInt32 ataChannel )
{
    UInt16  cmdPort = 0;
    UInt16  ctrPort = 0;
    UInt8   isaIrq  = 0;

    switch ( ataChannel )
    {
        case PRI_CHANNEL_ID:
            cmdPort = PRI_CMD_ADDR;
            ctrPort = PRI_CTR_ADDR;
            isaIrq  = PRI_ISA_IRQ;
            break;
        
        case SEC_CHANNEL_ID:
            cmdPort = SEC_CMD_ADDR;
            ctrPort = SEC_CTR_ADDR;
            isaIrq  = SEC_ISA_IRQ;
            break;
    }

    return createChannelInfo( ataChannel, cmdPort, ctrPort, isaIrq );
}