⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 isapnp.c

📁 威盛 wince5.0 bsp 包 for x86 系统, 支持 VT8601 等北桥
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
// -----------------------------------------------------------------------------
//
//      THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
//      ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
//      THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//      PARTICULAR PURPOSE.
//  
// -----------------------------------------------------------------------------
#include <windows.h>
#include <nkintr.h>
#include <ceddk.h>
#include <pc.h>


int             __cdecl _inp  (unsigned short);
unsigned short  __cdecl _inpw (unsigned short);
unsigned long   __cdecl _inpd (unsigned short);

int             __cdecl _outp (unsigned short, int);
unsigned short  __cdecl _outpw(unsigned short, unsigned short);
unsigned long   __cdecl _outpd(unsigned short, unsigned long);


//
// Plug and Play Card Control Registers
//

#define SET_READ_DATA_PORT          0x00
#define SERIAL_ISOLATION_PORT       0x01
#define CONFIG_CONTROL_PORT         0x02
#define WAKE_CSN_PORT               0x03
#define SET_CSN_PORT                0x06

//
// Config Control command
//

#define CONTROL_WAIT_FOR_KEY        0x02
#define CONTROL_RESET_CSN           0x04

#define NUMBER_CARD_ID_BYTES        9
#define NUMBER_CARD_ID_BITS         (NUMBER_CARD_ID_BYTES * 8)
#define CHECKSUMED_BITS             64
#define LFSR_SEED                   0x6A
#define ISOLATION_TEST_BYTE_1       0x55
#define ISOLATION_TEST_BYTE_2       0xAA

#define PNP_ISA_IO_BASE             ( (PUCHAR)0 )
#define PNP_ADDRESS_PORT            0x279
#define PNP_WRITE_DATA_PORT         0xA79
#define PNP_READ_DATA_PORT          0x203

#define pnpWriteAddress(data)       _outp ((USHORT) PNP_ADDRESS_PORT, (UCHAR)(data))
#define pnpWriteData(data)          _outp ((USHORT) PNP_WRITE_DATA_PORT, (UCHAR)(data))
#define pnpReadData()               _inp  ((USHORT) PNP_READ_DATA_PORT)

CRITICAL_SECTION    g_csISAConfig;

BOOL                g_bISAInitialized;
USHORT              g_usISAReadPort;
UCHAR               g_ucISANumberCSNs;


UCHAR PnPReadRegister       (PUCHAR pIOSpace, UCHAR ucRegNo);
void  PnPWriteRegister      (PUCHAR pIOSpace, UCHAR ucRegNo, UCHAR ucValue);
void  PnPSendInitiationKey  (PUCHAR pIOSpace);
void  PnPSetWaitForKey      (PUCHAR pIOSpace);
void  PnPWake               (PUCHAR pIOSpace, UCHAR ucCSN);
void  PnPReadSerialId       (PUCHAR pIOSpace, PUCHAR ucSerialId);
int   PnPReadResourceData   (PUCHAR pIOSpace, PUCHAR ucResourceData, int iDataSize);

int   PnPGetLogicalDeviceInfo(PUCHAR ucResourceData, int iDataSize, 
                              PISA_PNP_LOGICAL_DEVICE_INFO pDeviceInfo);

void SC_Sleep(DWORD);


// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
VOID
PnPIsolateCards (VOID)
{
    USHORT j;
    UCHAR  cardId[NUMBER_CARD_ID_BYTES];
    UCHAR  bit, bit7, checksum, byte1, byte2;
    ULONG  csn = 0;

    //
    // First send Initiation Key to all the PNP ISA cards to enable PnP auto-config
    // ports and put all cards in configuration mode.
    //

    PnPSendInitiationKey(NULL);

    //
    // Reset all Pnp ISA cards' CSN to 0 and return to wait-for-key state
    //

    pnpWriteAddress (CONFIG_CONTROL_PORT);
    pnpWriteData (CONTROL_WAIT_FOR_KEY | CONTROL_RESET_CSN);

    //
    // Delay 2 msec for cards to load initial configuration state.
    //

    SC_Sleep(2);

    //
    // Put cards into configuration mode to ready isolation process.
    // The hardware on each PnP Isa card expects 72 pairs of I/O read
    // access to the read data port.
    //

    PnPSendInitiationKey(NULL);

    //
    // Starting Pnp Isa card isolation process.
    //

    //
    // Send WAKE[CSN=0] to force all cards without CSN into isolation
    // state to set READ DATA PORT.
    //

    pnpWriteAddress(WAKE_CSN_PORT);
    pnpWriteData(0);

    //
    // Set read data port to current testing value.
    //

    pnpWriteAddress(SET_READ_DATA_PORT);
    pnpWriteData((UCHAR)(PNP_READ_DATA_PORT >> 2));

    //
    // Isolate one PnP ISA card until fail
    //

    while ( TRUE ) {

        //
        // Read serial isolation port to cause PnP cards in the isolation
        // state to compare one bit of the boards ID.
        //

        pnpWriteAddress(SERIAL_ISOLATION_PORT);

        //
        // We need to delay 1 msec prior to starting the first pair of isolation
        // reads and must wait 250usec between each subsequent pair of isolation
        // reads.  This delay gives the ISA cards time to access information from
        // possible very slow storage device.
        //

        SC_Sleep(1);

        memset(cardId, 0, NUMBER_CARD_ID_BYTES);
        checksum = LFSR_SEED;
        for ( j = 0; j < NUMBER_CARD_ID_BITS; j++ ) {

            //
            // Read card id bit by bit
            //

            byte1 = pnpReadData();
            byte2 = pnpReadData();
            bit = (byte1 == ISOLATION_TEST_BYTE_1) && (byte2 == ISOLATION_TEST_BYTE_2);
            cardId[j / 8] |= bit << (j % 8);
            if ( j < CHECKSUMED_BITS ) {

                //
                // Calculate checksum and only do it for the first 64 bits
                //

                bit7 = (((checksum & 2) >> 1) ^ (checksum & 1) ^ (bit)) << 7;
                checksum = (checksum >> 1) | bit7;
            }
            SC_Sleep(1);
        }

        //
        // Verify the card id we read is legitimate
        // First make sure checksum is valid.  Note zero checksum is considered valid.
        //

        if ( cardId[8] == 0 || checksum == cardId[8] ) {

            //
            // Next make sure cardId is not zero
            //

            byte1 = 0;
            for ( j = 0; j < NUMBER_CARD_ID_BYTES; j++ ) {
                byte1 |= cardId[j];
            }
            if ( byte1 != 0 ) {

                //
                // Make sure the vender EISA ID bytes are nonzero
                //

                if ( (cardId[0] & 0x7f) != 0 && cardId[1] != 0 ) {

                    pnpWriteAddress(SET_CSN_PORT);

                    pnpWriteData(++csn);

                    //
                    // Do Wake[CSN] command to put the newly isolated card to
                    // sleep state and other un-isolated cards to isolation
                    // state.
                    //

                    pnpWriteAddress(WAKE_CSN_PORT);
                    pnpWriteData(0);
                    continue;     // ... to isolate more cards ...
                }
            }
        }
        break;                // could not isolate more cards ...
    }

    //
    // Finaly put all cards into wait for key state.
    //

    pnpWriteAddress(CONFIG_CONTROL_PORT);
    pnpWriteData(CONTROL_WAIT_FOR_KEY);
    g_ucISANumberCSNs = (UCHAR) csn;
}



//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
VOID
ISAInitBusInfo()
{
    if ( g_bISAInitialized ) {
        return;
    }

    g_bISAInitialized = TRUE;

    InitializeCriticalSection(&g_csISAConfig);

    PnPIsolateCards();
    RETAILMSG(1, (TEXT("PnP ISA InitBusInfo : %d card(s) found\r\n"), g_ucISANumberCSNs));

    g_usISAReadPort = 0x203;
}



//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
ULONG
ISAGetBusDataByOffset(
                     IN ULONG BusNumber,
                     IN ULONG SlotNumber,
                     IN PVOID Buffer,
                     IN ULONG Offset,
                     IN ULONG Length
                     )
{
    UCHAR               ucCSNumber, ucLogicalDevice;
    UCHAR               ucSerialID[9];
    UCHAR               ucResourceData[2048];
    int                 iResourceLength;
    ULONG               ulReturn;

    if ( g_bISAInitialized == FALSE )
        ISAInitBusInfo();

    if ( g_ucISANumberCSNs == 0 || g_ucISANumberCSNs == ~0U ) {
        return (0);
    }

    ucCSNumber = (UCHAR)(SlotNumber >> 8);
    ucLogicalDevice = (UCHAR)SlotNumber;

    if ( ucCSNumber > g_ucISANumberCSNs || ucCSNumber == 0 ||
         (Offset == 0 && Length != sizeof(ISA_PNP_CONFIG)) ||
         (Offset == 1 && Length != sizeof(ISA_PNP_RESOURCES)) ||
         Offset > 1 ) {
        return (0);
    }

    EnterCriticalSection(&g_csISAConfig);

    PnPSendInitiationKey(PNP_ISA_IO_BASE);

    PnPWake(PNP_ISA_IO_BASE, ucCSNumber);

    if ( Offset == 0 ) {
        PISA_PNP_CONFIG     pPnPConfig = (PISA_PNP_CONFIG)Buffer;

        PnPReadSerialId(PNP_ISA_IO_BASE, ucSerialID);

        pPnPConfig->VendorID =
        ucSerialID[0] << 24 | ucSerialID[1] << 16 | ucSerialID[2] << 8 |
        ucSerialID[3];

        pPnPConfig->SerialNumber = 
        ucSerialID[7] << 24 | ucSerialID[6] << 16 | ucSerialID[5] << 8 |
        ucSerialID[4];

        iResourceLength = PnPReadResourceData(
                                             PNP_ISA_IO_BASE, ucResourceData, sizeof(ucResourceData));

        pPnPConfig->NumberLogicalDevices = PnPGetLogicalDeviceInfo(
                                                                  ucResourceData, sizeof(ucResourceData),
                                                                  pPnPConfig->LogicalDeviceInfo);

        ulReturn = sizeof(ISA_PNP_CONFIG);
    } else {
        PISA_PNP_RESOURCES  pPnPResources = (PISA_PNP_RESOURCES)Buffer;
        int                 i;
        UCHAR               ucActive;

        PnPWriteRegister(PNP_ISA_IO_BASE, 0x07, ucLogicalDevice);

        ucActive = PnPReadRegister(PNP_ISA_IO_BASE, 0x30);

        if ( ucActive ) {
            pPnPResources->Flags = ISA_PNP_RESOURCE_FLAG_ACTIVE;

            for ( i = 0; i < 4; i++ ) {
                pPnPResources->Memory24Descriptors[i].MemoryBase =
                PnPReadRegister(PNP_ISA_IO_BASE, (UCHAR)(0x40 + i * 8)) << 8;
                pPnPResources->Memory24Descriptors[i].MemoryBase |=
                (USHORT)PnPReadRegister(PNP_ISA_IO_BASE, (UCHAR)(0x41 + i * 8));
                pPnPResources->Memory24Descriptors[i].MemoryControl =
                PnPReadRegister(PNP_ISA_IO_BASE, (UCHAR)(0x42 + i * 8));
                pPnPResources->Memory24Descriptors[i].MemoryUpperLimit =
                (USHORT)(PnPReadRegister(PNP_ISA_IO_BASE, (UCHAR)(0x43 + i * 8)) << 8);
                pPnPResources->Memory24Descriptors[i].MemoryUpperLimit |=
                (USHORT)PnPReadRegister(PNP_ISA_IO_BASE, (UCHAR)(0x44 + i * 8));
            }

            for ( i = 0; i < 8; i++ ) {
                pPnPResources->IoPortDescriptors[i] =
                PnPReadRegister(PNP_ISA_IO_BASE, (UCHAR)(0x60 + i * 2)) << 8;
                pPnPResources->IoPortDescriptors[i] |=
                PnPReadRegister(PNP_ISA_IO_BASE, (UCHAR)(0x61 + i * 2));
            }

            pPnPResources->IRQDescriptors[0].IRQLevel = PnPReadRegister(PNP_ISA_IO_BASE, 0x70);
            pPnPResources->IRQDescriptors[0].IRQType = PnPReadRegister(PNP_ISA_IO_BASE, 0x71);
            pPnPResources->IRQDescriptors[1].IRQLevel = PnPReadRegister(PNP_ISA_IO_BASE, 0x72);
            pPnPResources->IRQDescriptors[1].IRQType = PnPReadRegister(PNP_ISA_IO_BASE, 0x73);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -