isapnp.c

来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 618 行 · 第 1/2 页

C
618
字号
/*++
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.
Copyright (c) 1995-1998  Microsoft Corporation

Module Name:

   isapnp.c

Abstract:

Notes:


--*/

#define WINCEMACRO 1

#include <windows.h>
#include <nkintr.h>

#undef DeviceIoControl
#include <oalio.h>
#include <wdmhal.h>
#include <altoona.h>
#include <hal.h>

#define PNP_ISA_IO_BASE     ( (PUCHAR)(PHYS_ADDR_IO_SPACE_BASE | 0xA0000000) )
#define PNP_ADDRESS_PORT    0x279
#define PNP_WRITE_DATA_PORT 0xA79

// CRITICAL_SECTION    g_csISAConfig;

BOOL                g_bISAInitialized;
USHORT              g_usISAReadPort = 0x20B;
UCHAR               g_ucISANumberCSNs;

int
PnPIsolate(PUCHAR pIOSpace);

UCHAR
PnPReadRegister(PUCHAR pIOSpace, UCHAR ucRegNo);

void
PnPWriteRegister(PUCHAR pIOSpace, UCHAR ucRegNo, UCHAR ucValue);

void
PnPSendInitiationKey(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
PnPSetWaitForKey(PUCHAR pIOSpace);

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

    g_bISAInitialized = TRUE;

//    InitializeCriticalSection(&g_csISAConfig);

    if (g_ucISANumberCSNs == 0)
    {
        g_ucISANumberCSNs = PnPIsolate(PNP_ISA_IO_BASE);

        if (g_ucISANumberCSNs == 0)
        {
            NKDbgPrintfW(TEXT("No ISA PnP cards detected\r\n"));

            g_ucISANumberCSNs = (UCHAR)~0U;
        }
    }
}

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_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);
            
            pPnPResources->DMADescriptors[0] = PnPReadRegister(PNP_ISA_IO_BASE, 0x74);
            
            pPnPResources->DMADescriptors[1] = PnPReadRegister(PNP_ISA_IO_BASE, 0x75);

            for (i = 0; i < 4; i++)
            {
                pPnPResources->Memory32Descriptors[i].MemoryBase =
                    PnPReadRegister(PNP_ISA_IO_BASE, (UCHAR)(0x76 + i * 16)) << 24;
                pPnPResources->Memory32Descriptors[i].MemoryBase |=
                    PnPReadRegister(PNP_ISA_IO_BASE, (UCHAR)(0x77 + i * 16)) << 16;
                pPnPResources->Memory32Descriptors[i].MemoryBase |=
                    PnPReadRegister(PNP_ISA_IO_BASE, (UCHAR)(0x78 + i * 16)) << 8;
                pPnPResources->Memory32Descriptors[i].MemoryBase |=
                    PnPReadRegister(PNP_ISA_IO_BASE, (UCHAR)(0x79 + i * 16));

                pPnPResources->Memory32Descriptors[i].MemoryControl =
                    PnPReadRegister(PNP_ISA_IO_BASE, (UCHAR)(0x7A + i * 16));

                pPnPResources->Memory32Descriptors[i].MemoryUpperLimit =
                    PnPReadRegister(PNP_ISA_IO_BASE, (UCHAR)(0x7B + i * 16)) << 24;
                pPnPResources->Memory32Descriptors[i].MemoryUpperLimit |=
                    PnPReadRegister(PNP_ISA_IO_BASE, (UCHAR)(0x7C + i * 16)) << 16;
                pPnPResources->Memory32Descriptors[i].MemoryUpperLimit |=
                    PnPReadRegister(PNP_ISA_IO_BASE, (UCHAR)(0x7D + i * 16)) << 8;
                pPnPResources->Memory32Descriptors[i].MemoryUpperLimit |=
                    PnPReadRegister(PNP_ISA_IO_BASE, (UCHAR)(0x7E + i * 16));
            }
            
        }
        else
        {
            pPnPResources->Flags = 0;
        }

        ulReturn = sizeof(ISA_PNP_RESOURCES);
    }

    PnPSetWaitForKey(PNP_ISA_IO_BASE);
    
//    LeaveCriticalSection(&g_csISAConfig);

    return ulReturn;
}

ULONG
ISASetBusDataByOffset(
    IN ULONG BusNumber,
    IN ULONG SlotNumber,
    IN PVOID Buffer,
    IN ULONG Offset,
    IN ULONG Length
    )
{
    UCHAR               ucCSNumber, ucLogicalDevice;
    PISA_PNP_RESOURCES  pPnPResources = (PISA_PNP_RESOURCES)Buffer;
    int                 i;


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

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

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

//    EnterCriticalSection(&g_csISAConfig);

    PnPSendInitiationKey(PNP_ISA_IO_BASE);

    PnPWake(PNP_ISA_IO_BASE, ucCSNumber);

    PnPWriteRegister(PNP_ISA_IO_BASE, 0x07, ucLogicalDevice);
    
    if (pPnPResources->Flags & ISA_PNP_RESOURCE_FLAG_ACTIVE)
    {
        for (i = 0; i < 4; i++)
        {
            PnPWriteRegister(
                PNP_ISA_IO_BASE, (UCHAR)(0x40 + i * 8),
                (UCHAR)(pPnPResources->Memory24Descriptors[i].MemoryBase >> 8));
            PnPWriteRegister(
                PNP_ISA_IO_BASE, (UCHAR)(0x41 + i * 8),
                (UCHAR)(pPnPResources->Memory24Descriptors[i].MemoryBase));

            PnPWriteRegister(
                PNP_ISA_IO_BASE, (UCHAR)(0x42 + i * 8),
                pPnPResources->Memory24Descriptors[i].MemoryControl);

            PnPWriteRegister(
                PNP_ISA_IO_BASE, (UCHAR)(0x43 + i * 8),
                (UCHAR)(pPnPResources->Memory24Descriptors[i].MemoryUpperLimit >> 8));
            PnPWriteRegister(
                PNP_ISA_IO_BASE, (UCHAR)(0x44 + i * 8),
                (UCHAR)(pPnPResources->Memory24Descriptors[i].MemoryUpperLimit));
        }
        
        for (i = 0; i < 8; i++)
        {
            PnPWriteRegister(
                PNP_ISA_IO_BASE, (UCHAR)(0x60 + i * 2),
                (UCHAR)(pPnPResources->IoPortDescriptors[i] >> 8));
            PnPWriteRegister(
                PNP_ISA_IO_BASE, (UCHAR)(0x61 + i * 2),
                (UCHAR)(pPnPResources->IoPortDescriptors[i]));
        }
        
        PnPWriteRegister(PNP_ISA_IO_BASE, 0x70, pPnPResources->IRQDescriptors[0].IRQLevel);
        PnPWriteRegister(PNP_ISA_IO_BASE, 0x71, pPnPResources->IRQDescriptors[0].IRQType);

⌨️ 快捷键说明

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