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

📄 pcienum.cpp

📁 WINCE5.0操作系统下的PCI总线驱动
💻 CPP
📖 第 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.
//

//
// Routines to Bus Support the PCIbus
//
#include <windows.h>
#include <types.h>
#include <pcienum.h>
#include <pcidbg.h>
#include <pcibus.h>
#include <CeBusCfg.h>

PciDeviceFolder::PciDeviceFolder(LPCTSTR lpBusName,LPCTSTR lpTemplateRegPath,DWORD dwBusType, DWORD BusNumber,PCI_SLOT_NUMBER SlotNumber,HANDLE hParent)
:   DeviceFolder(lpBusName,lpTemplateRegPath,dwBusType,BusNumber,SlotNumber.u.bits.DeviceNumber,SlotNumber.u.bits.FunctionNumber, hParent)
{
    m_CurPowerState=D0;
    m_CurSleepPowerState = D4;
    m_ConfigureIsBackuped = FALSE;;
    m_pCfg= new PCI_COMMON_CONFIG;
    m_fAlwaysBackup = FALSE;
    m_dwPowerMgrOffset = 0;
    FindPCIPowerMgrInterface();
}
PciDeviceFolder::~PciDeviceFolder()
{
    if (m_pCfg)
        delete m_pCfg;
}
// PCI Power Handling;
BOOL PciDeviceFolder::SetPowerState(CEDEVICE_POWER_STATE newPowerState)
{
    Lock();
    if (m_pCfg) {
        if (newPowerState==D4 && m_CurPowerState!=D4) { // Change from DX to D4. backup the configuration.
            m_ConfigureIsBackuped= BackupConfiguration();
        };
        if (newPowerState!=D4 && m_CurPowerState == D4) { // Out or D4, restore the configurate
            if (m_ConfigureIsBackuped) {
                RestoreConfiguration();
                m_ConfigureIsBackuped = FALSE;
            }
        }
    }
    if (newPowerState!=m_CurPowerState) {
        SetPciPowerState(newPowerState);
        m_CurPowerState=newPowerState;
    };
    // When SetPowerState is called. It means this driver is under Power Managment Control.
    // Sleep Power State is no longer D4. It is always sync with Currrent Power State.
    m_CurSleepPowerState = newPowerState;
    Unlock();
    return TRUE;
}
BOOL PciDeviceFolder::PowerUp()
{
    if (GetDeviceHandle()!=NULL &&  m_CurPowerState != m_CurSleepPowerState&& m_pCfg && m_ConfigureIsBackuped ) {
        SetPciPowerState(m_CurPowerState);
        if (m_CurSleepPowerState == D4 ||  m_fAlwaysBackup ) {
            RestoreConfiguration();
            m_ConfigureIsBackuped = FALSE;
        }
        SetPciPowerState(m_CurPowerState);
    }
    return TRUE;
}
BOOL PciDeviceFolder::PowerDown()
{
    if (GetDeviceHandle()!=NULL && m_CurPowerState != m_CurSleepPowerState && m_pCfg ) {
        if (m_CurSleepPowerState == D4 ||  m_fAlwaysBackup )
            m_ConfigureIsBackuped= BackupConfiguration();
        SetPciPowerState(m_CurSleepPowerState);                
    }
    return TRUE;
}
BOOL PciDeviceFolder::RestoreConfiguration()
{
    if (m_pCfg) {
        CE_BUS_DEVICE_CONFIGURATION_DATA deviceConfigData;
        deviceConfigData.lpDeviceBusName=NULL;
        deviceConfigData.dwSpace=PCI_WHICHSPACE_CONFIG;
        deviceConfigData.dwOffset=0;
        deviceConfigData.dwLength = sizeof(PCI_COMMON_CONFIG);
        deviceConfigData.pBuffer = m_pCfg;
        return SetConfigurationData(&deviceConfigData);
    }
    else
        return FALSE;
}
BOOL PciDeviceFolder::BackupConfiguration()
{
    if (m_pCfg) {
        CE_BUS_DEVICE_CONFIGURATION_DATA deviceConfigData;
        deviceConfigData.lpDeviceBusName=NULL;
        deviceConfigData.dwSpace=PCI_WHICHSPACE_CONFIG;
        deviceConfigData.dwOffset=0;
        deviceConfigData.dwLength = sizeof(PCI_COMMON_CONFIG);
        deviceConfigData.pBuffer = m_pCfg;
        m_ConfigureIsBackuped = GetConfigurationData(&deviceConfigData);
        return (m_ConfigureIsBackuped);
    }
    else
        return FALSE;
}
BOOL PciDeviceFolder::FindPCIPowerMgrInterface()
{
    PCI_COMMON_CONFIG pciCmnCfg;
    CE_BUS_DEVICE_CONFIGURATION_DATA deviceConfigData;
    deviceConfigData.lpDeviceBusName=NULL;
    deviceConfigData.dwSpace=PCI_WHICHSPACE_CONFIG;
    deviceConfigData.dwOffset=0;
    deviceConfigData.dwLength = sizeof(PCI_COMMON_CONFIG);
    deviceConfigData.pBuffer =  &pciCmnCfg;
    if (GetConfigurationData(&deviceConfigData)) { 
        if (pciCmnCfg.Status & 0x10) { // This one support Power Mgr.
            DWORD dwCapPtr = 0;
            // Search to find Power Mgr Register.
            switch (pciCmnCfg.HeaderType & 0x7f) {
            case PCI_DEVICE_TYPE: // PCI Bus Power Mgr Specification 3.1.1
                dwCapPtr = *(((PBYTE)&pciCmnCfg)+ 0x34);
                break;
            case PCI_BRIDGE_TYPE:
                dwCapPtr = *(((PBYTE)&pciCmnCfg)+ 0x34);
                break;
            case PCI_CARDBUS_TYPE:
                dwCapPtr = *(((PBYTE)&pciCmnCfg)+ 0x14);
                break;
            default:
                break;
            }
            if (dwCapPtr!=0 && dwCapPtr <= sizeof(pciCmnCfg) - sizeof(PCI_POWER_MANAGEMENT_BLOCK) ) {
                PPCI_POWER_MANAGEMENT_BLOCK pPmcBlock =(PPCI_POWER_MANAGEMENT_BLOCK)(((PBYTE)&pciCmnCfg) + dwCapPtr);
                // Search for PM Regs.
                while (pPmcBlock->CapabilityID!=0x1 && pPmcBlock->NextItemPtr != NULL
                        && pPmcBlock->NextItemPtr <= sizeof(pciCmnCfg) - sizeof(PCI_POWER_MANAGEMENT_BLOCK))  {
                    pPmcBlock = (PPCI_POWER_MANAGEMENT_BLOCK)(((PBYTE)&pciCmnCfg) + pPmcBlock->NextItemPtr);
                }
                if (pPmcBlock->CapabilityID==0x1 
                        && pPmcBlock->NextItemPtr <= sizeof(pciCmnCfg) - sizeof(PCI_POWER_MANAGEMENT_BLOCK))  {
                    // We found it.
                    m_dwPowerMgrOffset = (DWORD)((PBYTE)pPmcBlock - (PBYTE)&pciCmnCfg);
                    ASSERT( m_dwPowerMgrOffset < sizeof(pciCmnCfg)  - sizeof(PCI_POWER_MANAGEMENT_BLOCK));
                    CE_BUS_DEVICE_CONFIGURATION_DATA deviceConfigData1;
                    deviceConfigData1.lpDeviceBusName=NULL;
                    deviceConfigData1.dwSpace=PCI_WHICHSPACE_CONFIG;
                    deviceConfigData1.dwOffset= m_dwPowerMgrOffset ;
                    deviceConfigData1.dwLength = sizeof(m_PowerMgrBlock);
                    deviceConfigData1.pBuffer =  &m_PowerMgrBlock;
                    if (!GetConfigurationData(&deviceConfigData1)) { // If this fails. Make it un-spported.
                        m_dwPowerMgrOffset=0;
                    }
                    
                }
            }
        }
    }
    return  (m_dwPowerMgrOffset!=0);
}
BOOL PciDeviceFolder::SetPciPowerState(CEDEVICE_POWER_STATE curPowerState)
{
    BOOL bReturn = FALSE;
    if (m_dwPowerMgrOffset!=0) {
        CE_BUS_DEVICE_CONFIGURATION_DATA deviceConfigData;
        deviceConfigData.lpDeviceBusName=NULL;
        deviceConfigData.dwSpace=PCI_WHICHSPACE_CONFIG;
        deviceConfigData.dwOffset=0;
        deviceConfigData.dwLength = sizeof(m_PowerMgrBlock);
        deviceConfigData.pBuffer =  &m_PowerMgrBlock;
        if (!GetConfigurationData(&deviceConfigData)) { // If this fails. Make it un-spported.
            // PCI Power Mgr Spec 3.2.4
            DWORD dwPciState = 0;
            switch ( curPowerState) {
            case D0:
            default:
                dwPciState = 0;
                break;
            case D1:
                dwPciState = 1;
                break;
            case D2: 
                dwPciState = 2;
                break;
            case D3:  { // We only consern about wakeup source.
                // find next Higher state that can support wakeup source.
                DWORD dwBit = 0x4000; // Bit 14(D3) for D3 hot
                for (dwPciState = 3 ; dwPciState!=0; dwPciState -- ) {
                    if ((m_PowerMgrBlock.PMC & dwBit)!=0)
                        break;
                    dwBit >>=1;
                }
                break;
            }
            case D4:
                dwPciState = 3;
                break;
            }
            m_PowerMgrBlock.PMCSR = ((m_PowerMgrBlock.PMCSR) & (~0x3)) + (UINT16)(dwPciState & 0x3);
            deviceConfigData.lpDeviceBusName=NULL;
            deviceConfigData.dwSpace=PCI_WHICHSPACE_CONFIG;
            deviceConfigData.dwOffset=0;
            deviceConfigData.dwLength = sizeof(m_PowerMgrBlock);
            deviceConfigData.pBuffer =  &m_PowerMgrBlock;
            bReturn = SetConfigurationData(&deviceConfigData);
        }
    }
    return bReturn;
}
//-------------------------------------PCI Bus Driver -------------------------------------------------------
PciBusEnum::PciBusEnum(LPCTSTR lpActiveRegPath,LPCTSTR lpInstanceRegPath)
:   DefaultBusDriver(lpActiveRegPath)
,   m_ActiveKey(HKEY_LOCAL_MACHINE, lpActiveRegPath)
,   m_DeviceKey(HKEY_LOCAL_MACHINE,lpInstanceRegPath)
{
    DEBUGMSG(ZONE_ENUM| ZONE_INIT,(TEXT("BusEnum::BusEnum (ActivateRegPath=%s)\r\n"),lpActiveRegPath));
    // Get DEVLOAD_DEVKEY_VALNAME name
    m_lpActiveRegPath = NULL;
    DWORD dwKeyLen=0;
    if (lpInstanceRegPath!=NULL) {
        dwKeyLen = _tcslen(lpInstanceRegPath) + 1;
        m_lpActiveRegPath = new TCHAR [dwKeyLen];
        if ( m_lpActiveRegPath) {
            _tcscpy(m_lpActiveRegPath,lpInstanceRegPath);
            m_lpActiveRegPath [dwKeyLen-1]= 0;
        }
    }
        
    m_lpStrInitParam = NULL;
    m_dwNumOfInitParam =0 ;
    m_lpBusName = NULL;
    m_dwBusNumber = 0;
    m_dwDeviceIndex = 0;
    m_dwCfgAlwaysBackup = 0;

}
PciBusEnum::~PciBusEnum()
{
    if (m_lpStrInitParam )
        delete m_lpStrInitParam ;
    if ( m_lpBusName)
        delete  m_lpBusName;
    if (m_lpActiveRegPath) 
        delete m_lpActiveRegPath;
}
#define BUSNAMEUNKNOWN TEXT("UnknownBus")
BOOL PciBusEnum::Init()
{
    BOOL  bReturn = FALSE;
    // Initialize InitParam
    if ( m_lpActiveRegPath==NULL || !m_ActiveKey.IsKeyOpened()) {
        DEBUGMSG(ZONE_ENUM|ZONE_ERROR,(TEXT("PciBusEnum!Init RegOpenKeyEx() return FALSE!!!\r\n")));
        return FALSE;
    }
    if (m_lpStrInitParam == NULL ) {
        DWORD dwKeyLen=0;
        DWORD dwType;
        // BC. It is BC with RegEnum We may want remove this later
        // What this key contain multi-string that indicate the reigstry has such name will copy into active registry
        if (m_ActiveKey.RegQueryValueEx(DEVLOAD_REPARMS_VALNAME, &dwType,NULL,&dwKeyLen) && dwType== REG_MULTI_SZ && dwKeyLen!=0 ) {
            dwKeyLen = (dwKeyLen + sizeof(TCHAR) -1 ) / sizeof(TCHAR);
            m_lpStrInitParam = new TCHAR [ dwKeyLen ];
            if (m_lpStrInitParam) {
                if (m_ActiveKey.GetRegValue(DEVLOAD_REPARMS_VALNAME,(LPBYTE)m_lpStrInitParam,dwKeyLen * sizeof(TCHAR))) {
                    DWORD dwUnitCount= dwKeyLen;                        
                    for (LPTSTR lpCurPos = m_lpStrInitParam;
                            m_dwNumOfInitParam< MAX_INITPARAM && dwUnitCount!=0 && *lpCurPos!=0 ; 
                            m_dwNumOfInitParam++) {
                        m_lpInitParamArray[m_dwNumOfInitParam] = lpCurPos;
                        while (*lpCurPos!=0 && dwUnitCount!=0  ) {
                            lpCurPos++;
                            dwUnitCount --;
                        }
                        if (dwUnitCount) {
                            lpCurPos ++;
                            dwUnitCount --;
                        }
                        else 
                            break;
                    }
                            
                }
            }
        }
    }
    if (!m_ActiveKey.IsKeyOpened() || !m_ActiveKey.GetRegValue(PCI_ALWAYSBACKUP,(LPBYTE)m_dwCfgAlwaysBackup,sizeof(m_dwCfgAlwaysBackup))) {
        m_dwCfgAlwaysBackup = 0;
    }
    // Scan And Enum All the driver in registry.
    if ( GetDeviceHandle()!=NULL &&  m_DeviceKey.IsKeyOpened()) {
        DWORD dwKeyLen=0;
        DWORD dwType;
        if (!m_DeviceKey.GetRegValue(DEVLOAD_INTERFACETYPE_VALNAME,(PUCHAR) &m_dwBusType,sizeof(m_dwBusType))) {
            // No interface type defined
            m_dwBusType=InterfaceTypeUndefined;
        };
        dwKeyLen=0;
        if (m_lpBusName == NULL && m_DeviceKey.RegQueryValueEx(DEVLOAD_BUSNAME_VALNAME, &dwType,NULL,&dwKeyLen) && dwType== DEVLOAD_BUSNAME_VALTYPE && dwKeyLen!=0 ) {
            dwKeyLen = (dwKeyLen + sizeof(TCHAR) -1) / sizeof(TCHAR);
            m_lpBusName = new TCHAR[dwKeyLen];
            if (m_lpBusName ) {
                m_DeviceKey.GetRegValue(DEVLOAD_BUSNAME_VALNAME, (LPBYTE )m_lpBusName, dwKeyLen*sizeof(TCHAR) );
                m_lpBusName [dwKeyLen-1]=0;
            }
        }
        if (!m_DeviceKey.GetRegValue(DEVLOAD_BUSNUMBER_VALNAME , (LPBYTE)m_dwBusNumber,sizeof(m_dwBusNumber)))
            m_dwBusNumber=0;
        

⌨️ 快捷键说明

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