isapnp.c

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

C
618
字号
        PnPWriteRegister(PNP_ISA_IO_BASE, 0x72, pPnPResources->IRQDescriptors[1].IRQLevel);
        PnPWriteRegister(PNP_ISA_IO_BASE, 0x73, pPnPResources->IRQDescriptors[1].IRQType);
        
        PnPWriteRegister(PNP_ISA_IO_BASE, 0x74, pPnPResources->DMADescriptors[0]);
        PnPWriteRegister(PNP_ISA_IO_BASE, 0x75, pPnPResources->DMADescriptors[1]);
        
        for (i = 0; i < 4; i++)
        {
            PnPWriteRegister(
                PNP_ISA_IO_BASE, (UCHAR)(0x76 + i * 16),
                (UCHAR)(pPnPResources->Memory32Descriptors[i].MemoryBase >> 24));
            PnPWriteRegister(
                PNP_ISA_IO_BASE, (UCHAR)(0x77 + i * 16),
                (UCHAR)(pPnPResources->Memory32Descriptors[i].MemoryBase >> 16));
            PnPWriteRegister(
                PNP_ISA_IO_BASE, (UCHAR)(0x78 + i * 16),
                (UCHAR)(pPnPResources->Memory32Descriptors[i].MemoryBase >> 8));
            PnPWriteRegister(
                PNP_ISA_IO_BASE, (UCHAR)(0x79 + i * 16),
                (UCHAR)(pPnPResources->Memory32Descriptors[i].MemoryBase));
            PnPWriteRegister(
                PNP_ISA_IO_BASE, (UCHAR)(0x7A + i * 16),
                pPnPResources->Memory32Descriptors[i].MemoryControl);
            PnPWriteRegister(
                PNP_ISA_IO_BASE, (UCHAR)(0x7B + i * 16),
                (UCHAR)(pPnPResources->Memory32Descriptors[i].MemoryUpperLimit >> 24));
            PnPWriteRegister(
                PNP_ISA_IO_BASE, (UCHAR)(0x7C + i * 16),
                (UCHAR)(pPnPResources->Memory32Descriptors[i].MemoryUpperLimit >> 16));
            PnPWriteRegister(
                PNP_ISA_IO_BASE, (UCHAR)(0x7D + i * 16),
                (UCHAR)(pPnPResources->Memory32Descriptors[i].MemoryUpperLimit >> 8));
            PnPWriteRegister(
                PNP_ISA_IO_BASE, (UCHAR)(0x7E + i * 16),
                (UCHAR)(pPnPResources->Memory32Descriptors[i].MemoryUpperLimit));
        }

        PnPWriteRegister(PNP_ISA_IO_BASE, 0x30, 1);
    }
    else
    {
        PnPWriteRegister(PNP_ISA_IO_BASE, 0x30, 0);
    }
        

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

    return sizeof(ISA_PNP_RESOURCES);
}

int
PnPIsolate(PUCHAR pIOSpace)
{
    UCHAR   ucSerialID[9];
    int     nDevices = 0;
    BOOL    bFirst = TRUE;
    int     i, timeOut;
    UCHAR   ucChecksum;
    DWORD   dwStartTickCount, dwCurrentTickCount;
    extern  DWORD SC_GetTickCount(void);

    PnPSendInitiationKey(pIOSpace);

    for ( ; ; )
    {
        PnPWake(pIOSpace, 0);

        if (bFirst)
        {
            bFirst = FALSE;

            //
            // Set PNP_READ_DATA_PORT
            //
            PnPWriteRegister(pIOSpace, 0x00, g_usISAReadPort >> 2);
        }

        memset(ucSerialID, 0, sizeof(ucSerialID));

        ucChecksum = 0x6A;

        WRITE_PORT_UCHAR(pIOSpace + PNP_ADDRESS_PORT, 0x01);

        dwStartTickCount = SC_GetTickCount();
        timeOut = 0;

        do
        {
            dwCurrentTickCount = SC_GetTickCount();
            if (timeOut++ > CPU_CLOCK_FRQUENCY/5000) break;
        }
        while (dwStartTickCount <= dwCurrentTickCount &&
            (dwStartTickCount + 2) > dwCurrentTickCount);

        for (i = 0; i < 72; i++)
        {
            UCHAR   bit, bit7, ucChar1, ucChar2;

            ucChar1 = READ_PORT_UCHAR(pIOSpace + g_usISAReadPort);
            ucChar2 = READ_PORT_UCHAR(pIOSpace + g_usISAReadPort);

            bit = ucChar1 == 0x55 && ucChar2 == 0xAA;

            ucSerialID[i / 8] |= bit << (i % 8);

            if (i < 64)
            {
                bit7 = (((ucChecksum & 2) >> 1) ^ (ucChecksum & 1) ^ (bit)) << 7;
                ucChecksum = (ucChecksum >> 1) | bit7;
            }

            dwStartTickCount = SC_GetTickCount();
            timeOut = 0;
            do
            {
                dwCurrentTickCount = SC_GetTickCount();
                if (timeOut++ > CPU_CLOCK_FRQUENCY/5000 ) break;
            }
            while (dwStartTickCount <= dwCurrentTickCount &&
                (dwStartTickCount + 2) > dwCurrentTickCount);

        }

        if (ucSerialID[0] != 0 && ucSerialID[1] != 0 &&
            (ucSerialID[8] == 0 || ucChecksum == ucSerialID[8]))
        {
            PnPWriteRegister(pIOSpace, 0x06, ++nDevices);
        }
        else
        {
            break;
        }
    }

    PnPSetWaitForKey(pIOSpace);

    return nDevices;
}

UCHAR
PnPReadRegister(PUCHAR pIOSpace, UCHAR ucRegNo)
{
    WRITE_PORT_UCHAR(pIOSpace + PNP_ADDRESS_PORT, ucRegNo);
    return READ_PORT_UCHAR(pIOSpace + g_usISAReadPort);
}    

void
PnPWriteRegister(PUCHAR pIOSpace, UCHAR ucRegNo, UCHAR ucValue)
{
    WRITE_PORT_UCHAR(pIOSpace + PNP_ADDRESS_PORT, ucRegNo);
    WRITE_PORT_UCHAR(pIOSpace + PNP_WRITE_DATA_PORT, ucValue);
}

void
PnPSendInitiationKey(PUCHAR pIOSpace)
{
    int             i;
    static  UCHAR   ucInitKey[] =
    {
        0x00, 0x00,
        0x6A, 0xB5, 0xDA, 0xED, 0xF6, 0xFB, 0x7D, 0xBE,
        0xDF, 0x6F, 0x37, 0x1B, 0x0D, 0x86, 0xC3, 0x61,
        0xB0, 0x58, 0x2C, 0x16, 0x8B, 0x45, 0xA2, 0xD1,
        0xE8, 0x74, 0x3A, 0x9D, 0xCE, 0xE7, 0x73, 0x39
    };
    
    
    for (i = 0; i < sizeof(ucInitKey); i++)
    {
        WRITE_PORT_UCHAR(pIOSpace + PNP_ADDRESS_PORT, ucInitKey[i]);
    }
}

void
PnPWake(PUCHAR pIOSpace, UCHAR ucCSN)
{
    PnPWriteRegister(pIOSpace, 0x03, ucCSN);
}
        
void
PnPReadSerialId(PUCHAR pIOSpace, PUCHAR ucSerialId)
{
    int     i;

    for (i = 0; i < 9; i++)
    {
        WRITE_PORT_UCHAR(pIOSpace + PNP_ADDRESS_PORT, 0x05);
        
        while (!(READ_PORT_UCHAR(pIOSpace + g_usISAReadPort) & 0x01))
            ;
            
        WRITE_PORT_UCHAR(pIOSpace + PNP_ADDRESS_PORT, 0x04);
        ucSerialId[i] = READ_PORT_UCHAR(pIOSpace + g_usISAReadPort);
    }
}

int
PnPReadResourceData(PUCHAR pIOSpace, PUCHAR ucResourceData, int iDataSize)
{
    int     i;
    int     bSawEndTag = FALSE;
    UCHAR   ucChecksum = 0;

    for (i = 0; i < iDataSize; i++)
    {
        WRITE_PORT_UCHAR(pIOSpace + PNP_ADDRESS_PORT, 0x05);
        
        while (!(READ_PORT_UCHAR(pIOSpace + g_usISAReadPort) & 0x01))
            ;
            
        WRITE_PORT_UCHAR(pIOSpace + PNP_ADDRESS_PORT, 0x04);
        ucResourceData[i] = READ_PORT_UCHAR(pIOSpace + g_usISAReadPort);

        ucChecksum += ucResourceData[i];
        
        if (bSawEndTag)
        {
            if (ucResourceData[i] != 0 && ucChecksum != 0)
            {
                DEBUGMSG(1, (TEXT("Bad resource checksum\n")));
            }

            i++;
            break;
        }
        
        if (ucResourceData[i] == 0x79)
        {
            bSawEndTag = 1;
        }
    }
    
    return i;
}

int
PnPGetLogicalDeviceInfo(
    PUCHAR ucResourceData, int iDataSize, 
    PISA_PNP_LOGICAL_DEVICE_INFO pDeviceInfo)
{
    PUCHAR  pCurrent;
    int     iLength, iName;
    int     i;
    int     nDevices = 0, nCompatibleIDs = 0;
    
    pCurrent = ucResourceData;

    memset(pDeviceInfo, 0, sizeof(ISA_PNP_LOGICAL_DEVICE_INFO) * 8);
    
    for (i = 0; i < iDataSize; i++)
    {
        if ((*pCurrent & 0x80) == 0)
        {
            //
            // Small TAG
            //
            
            iName = (*pCurrent >> 3) & 0x0F;
            iLength = (*pCurrent & 0x07) + 1;
            
            switch (iName)
            {
            case 2:     // Logical Device ID
                if (nDevices <= 8)
                {
                    nDevices++;
                    nCompatibleIDs = 0;
                    pDeviceInfo[nDevices - 1].LogicalDeviceID =
                        pCurrent[1] << 24 | pCurrent[2] << 16 | pCurrent[3] << 8 |
                        pCurrent[4];
                }
                break;

            case 3:     // Compatible Device ID
                if (nDevices <= 8)
                {
                    nCompatibleIDs++;
                    pDeviceInfo[nDevices - 1].CompatibleIDs[nCompatibleIDs - 1] =
                        pCurrent[1] << 24 | pCurrent[2] << 16 | pCurrent[3] << 8 |
                        pCurrent[4];
                }
                break;
            }
        }
        else
        {
            //
            // Large TAG
            //
            
            iName = *pCurrent & 0x7F;
            iLength = ((pCurrent[2] << 8) | pCurrent[1]) + 3;
        }
            
        pCurrent += iLength;
        i += iLength - 1;
    }
    
    return nDevices;
}

void
PnPSetWaitForKey(PUCHAR pIOSpace)
{
    PnPWriteRegister(pIOSpace, 0x02, 0x02);
}

⌨️ 快捷键说明

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