init.c

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

C
539
字号
/*++
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-2000 Microsoft Corporation.  All rights reserved.

Module Name:  

Abstract:

    Platform dependent PCMCIA initialization functions

Notes: 
--*/

#include <windows.h>
#include <types.h>
#include <cardserv.h>
#include <sockserv.h>
#include <sockpd.h>
#include <ceddk.h>
#include <nkintr.h>

extern VOID InitSocketNoCard(UINT uSocket);

DWORD gIntrPcmciaState;
DWORD gIntrPcmciaLevel;
DWORD g_Irq;

PUCHAR g_PCICIndex;
PUCHAR g_PCICData;
CRITICAL_SECTION g_PCIC_Crit;

#define PCMCIA_IRQ    11

//#define TEST_REGISTRY_CONFIG 1
#ifdef TEST_REGISTRY_CONFIG
//#define PCMCIA_IRQ    11
#define PCMCIA_IOBASE 0x3E0
#define PCMCIA_IOLEN  2
#endif

#define PCMCIA_DRIVER_KEY TEXT("Drivers\\PCMCIA")

#define SYSINTR_VALUE_NAME    TEXT("SysIntr")
#define IOBASE_VALUE_NAME TEXT("IoBase")
#define IOLEN_VALUE_NAME  TEXT("IoLen")

//
// Function to get the IRQ and I/O port range from the registry
//
// NOTE: lpRegPath is assumed to be under HKEY_LOCAL_MACHINE
//
// Returns ERROR_SUCCESS on success or a Win32 error code on failure
//
DWORD
GetRegistryConfig(
    LPWSTR lpRegPath,
    DWORD * lpdwSysIntr,
    DWORD * lpdwIoBase,
    DWORD * lpdwIoLen
    )
{
    HKEY hConfig;
    DWORD dwData;
    DWORD dwSize;
    DWORD dwType;
    DWORD dwRet;

    dwRet = RegOpenKeyEx(
                HKEY_LOCAL_MACHINE,
                lpRegPath,
                0,
                0,
                &hConfig);
    if (dwRet != ERROR_SUCCESS) {
        DEBUGMSG(ZONE_PDD,
            (TEXT("PCMCIA:GetRegistryConfig RegOpenKeyEx(%s) failed %d\r\n"),
            lpRegPath, dwRet));
        return dwRet;
    }

    dwSize = sizeof(DWORD);
    dwRet = RegQueryValueEx(
                hConfig,
                SYSINTR_VALUE_NAME,
                0,
                &dwType,
                (PUCHAR)&dwData,
                &dwSize);
    if (dwRet != ERROR_SUCCESS) {
        DEBUGMSG(ZONE_PDD,
            (TEXT("PCMCIA:GetRegistryConfig RegQueryValueEx(%s) failed %d\r\n"),
            SYSINTR_VALUE_NAME, dwRet));
        goto grc_fail;
    }
    *lpdwSysIntr = dwData;

    dwSize = sizeof(DWORD);
    dwRet = RegQueryValueEx(
                hConfig,
                IOBASE_VALUE_NAME,
                0,
                &dwType,
                (PUCHAR)&dwData,
                &dwSize);
    if (dwRet != ERROR_SUCCESS) {
        DEBUGMSG(ZONE_PDD,
            (TEXT("PCMCIA:GetRegistryConfig RegQueryValueEx(%s) failed %d\r\n"),
            IOBASE_VALUE_NAME, dwRet));
        goto grc_fail;
    }
    *lpdwIoBase = dwData;

    dwSize = sizeof(DWORD);
    dwRet = RegQueryValueEx(
                hConfig,
                IOLEN_VALUE_NAME,
                0,
                &dwType,
                (PUCHAR)&dwData,
                &dwSize);
    if (dwRet != ERROR_SUCCESS) {
        DEBUGMSG(ZONE_PDD,
            (TEXT("PCMCIA:GetRegistryConfig RegQueryValueEx(%s) failed %d\r\n"),
            IOLEN_VALUE_NAME, dwRet));
        goto grc_fail;
    }
    *lpdwIoLen = dwData;

    dwRet = ERROR_SUCCESS;

grc_fail:
    RegCloseKey(hConfig);
    return dwRet;
}   // GetRegistryConfig


//
// Use HalTranslateBusAddress to get access to the requested I/O ports and
// update g_PCICIndex and g_PCICData accordingly.
//
BOOL
GetIOPorts(
    DWORD IoBase,
    DWORD IoLen
    )
{
    PUCHAR ioPortBase; 
    ULONG  inIoSpace;
    PHYSICAL_ADDRESS ioPhysicalBase;

    inIoSpace = 1;
    ioPhysicalBase.LowPart = IoBase;
    ioPhysicalBase.HighPart = 0;

    DEBUGMSG(ZONE_PDD, 
             (TEXT("PDCardInitServices : HalTranslateBusAddress\r\n")));
    if (HalTranslateBusAddress(Isa, 0, ioPhysicalBase,
                               &inIoSpace, &ioPhysicalBase)) {
        DEBUGMSG(ZONE_PDD, 
            (TEXT("PDCardInitServices : HalTranslateBusAddress - OK\r\n")));
        if (!inIoSpace) {
            DEBUGMSG(ZONE_PDD, (TEXT("PDCardInitServices : ! IO Space\r\n")));
            if ((ioPortBase = (PUCHAR)MmMapIoSpace(ioPhysicalBase, 
                                                   IoLen, FALSE)) == NULL) {
                DEBUGMSG(ZONE_PDD, (TEXT("Error mapping I/O Ports\r\n")));
                return FALSE;
            }
        } else {
            DEBUGMSG(ZONE_PDD, (TEXT("PDCardInitServices : IO Space\r\n")));
            ioPortBase = (PUCHAR)ioPhysicalBase.LowPart;
        }
    } else {
        DEBUGMSG(ZONE_PDD, (TEXT("Error translating I/O Ports.\r\n")));
        return FALSE;
    }

    g_PCICIndex = ioPortBase;
    g_PCICData = ioPortBase + 1;
    return TRUE;
}   // GetIOPorts
    

//
// Verify the PCIC's REG_CHIP_REVISION
//
// This bit of code looks in the 82365 chip revision register (PCIC index 0)
// to see if a valid 82365 is in the system.  The original code only
// recognized the 83h silicon revision.  This indicates REV C silicon from
// Intel.  However, Intel also had a very popular rev B version, and that's
// what the integrated PCMCIA controller on the AMD ElanSC400 emulated.  The
// silicon revision register for that version returned 82h.
//
BOOL IsValidPCICSig(void)
{
    UINT8 sig;

    PCICIndex(0, REG_CHIP_REVISION);
    switch (sig = PCICDataRead()) {
    case 0x82:
    case 0x83:
        DEBUGMSG(1, (TEXT("PCMCIA:IsValidPCICSig Valid CHIP_REVISION detected = 0x%x at 0x%x\r\n"), sig, g_PCICIndex));
        return TRUE;
    }
    DEBUGMSG(1, (TEXT("PCMCIA:IsValidPCICSig Invalid CHIP_REVISION = 0x%x at 0x%x!!!\r\n"), sig, g_PCICIndex));
    return FALSE;
}
    

#define INTEL_82365_COMPATIBLE  0x41d00e00
#define UNKNOWN_CHIPSET  0x04a90218

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
BOOL private_InitPnP(int IoBase, int Irq)

{
   ULONG nTmpVal = 0;
   ISA_PNP_CONFIG      PnPInfo;
   ISA_PNP_RESOURCES   PnPResources;
   int                 nCSN;
   DWORD               nLogicalDevice;
   BOOL                bFoundIt;
   ULONG               ulReturn;
   
   DEBUGMSG(ZONE_PDD, (TEXT("PCMCIA Card reader: Init\r\n")));
   bFoundIt = FALSE;
   
   //
   // Scan the PnP ISA cards for a PCMCIA card reader/adaptor
   //
   for (nCSN = 1; ; nCSN++)
   {
      memset(&PnPInfo, 0, sizeof(PnPInfo));
      memset(&PnPResources, 0, sizeof(PnPResources));
      
      ulReturn = HalGetBusDataByOffset(PNPISAConfiguration, 0, nCSN << 8, &PnPInfo, 0, sizeof(PnPInfo));
      
      if (ulReturn == 0) {
         // Couldn't even get the card data, though it's supposed to exist.
         return FALSE;
      }

      for (nLogicalDevice = 0; nLogicalDevice < PnPInfo.NumberLogicalDevices; nLogicalDevice++)
      {
         if (INTEL_82365_COMPATIBLE == PnPInfo.LogicalDeviceInfo[nLogicalDevice].LogicalDeviceID ||
             UNKNOWN_CHIPSET == PnPInfo.LogicalDeviceInfo[nLogicalDevice].LogicalDeviceID)
         {
            bFoundIt = TRUE;
            break;
         }
      }
      
      if (bFoundIt)
         break;
   }
   
   
   if (!bFoundIt) {
      DEBUGMSG(ZONE_PDD,(TEXT("Couldn't find a suitable PnP Logical device\r\n")));
      return FALSE;
   }
   

   //
   // Get the resource information for this card.
   //

⌨️ 快捷键说明

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