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

📄 pcibus.c

📁 WINCE5.0操作系统下的PCI总线驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
            // ConfigDllName value doesn't exist
            wcscpy(pInfo->ConfigDllName, L"");
            ConfigDllExists = FALSE;
        }
    }
        
    //
    // Read Dll value (if it exists)
    //
    ValLen = sizeof(pInfo->DllName);
    Status = RegQueryValueEx(Key, DEVLOAD_DLLNAME_VALNAME, NULL, &ValType, (PUCHAR)pInfo->DllName, &ValLen);            
    if ((Status != ERROR_SUCCESS) || (ValType != DEVLOAD_DLLNAME_VALTYPE)) {
        // Dll value doesn't exist
        wcscpy(pInfo->DllName, L"");
        DllExists = FALSE;
    }

    // Make sure there is a DLL to load with the ConfigEntry
    if (pInfo->ConfigEntry) {
        if (!ConfigDllExists && !DllExists) {
            // Neither ConfigDll or Dll names exist, so invalidate ConfigEntry
            DEBUGMSG(ZONE_WARNING, (L"PCIBUS!RegGetInfo: Registry value '%s\\%s' exists but no '%s' or '%s' values are specified.  Ignoring '%s' value.\r\n",
                pInfo->RegPath, PCIBUS_CONFIGENTRY_VALNAME, PCIBUS_CONFIGDLL_VALNAME, DEVLOAD_DLLNAME_VALNAME, PCIBUS_CONFIGENTRY_VALNAME));
            
            pInfo->ConfigEntry = FALSE;
            wcscpy(pInfo->ConfigEntryName, L"");
        } else if (!ConfigDllExists && DllExists) {
            // No ConfigDll value, so use Dll value for ConfigEntry
            wcscpy(pInfo->ConfigDllName, pInfo->DllName);
        }
    }

    //
    // Read Flags value (if it exists)
    //
    ValLen = sizeof(pInfo->DevFlags);
    Status = RegQueryValueEx(Key, DEVLOAD_FLAGS_VALNAME, NULL, &ValType, (PUCHAR)&Val, &ValLen);            
    if ((Status == ERROR_SUCCESS) && (ValType == DEVLOAD_FLAGS_VALTYPE)) {
        // Flags value exists
        pInfo->DevFlags = Val;
    }

    //
    // Read Command value (if it exists)
    //
    ValLen = sizeof(Val);
    Status = RegQueryValueEx(Key, PCIBUS_COMMAND_VALNAME, NULL, &ValType, (PUCHAR)&Val, &ValLen);            
    if ((Status == ERROR_SUCCESS) && (ValType == PCIBUS_COMMAND_VALTYPE)) {
        // Command value exists
        pInfo->Command = Val;
    }

    //
    // Read BridgeCommand value (if it exists)
    //
    ValLen = sizeof(Val);
    Status = RegQueryValueEx(Key, PCIBUS_BRIDGECONTROL_VALNAME, NULL, &ValType, (PUCHAR)&Val, &ValLen);            
    if ((Status == ERROR_SUCCESS) && (ValType == PCIBUS_BRIDGECONTROL_VALTYPE)) {
        // BridgeControl value exists
        pInfo->BridgeControl = Val;
    }

    //
    // Read Latency value (if it exists)
    //
    ValLen = sizeof(Val);
    Status = RegQueryValueEx(Key, PCIBUS_LATENCY_VALNAME, NULL, &ValType, (PUCHAR)&Val, &ValLen);            
    if ((Status == ERROR_SUCCESS) && (ValType == PCIBUS_LATENCY_VALTYPE)) {
        // Latency value exists
        pInfo->Latency = Val;
    }

    //
    // Read Latency value (if it exists)
    //
    ValLen = sizeof(Val);
    Status = RegQueryValueEx(Key, PCIBUS_SECONDARYLATENCY_VALNAME, NULL, &ValType, (PUCHAR)&Val, &ValLen);            
    if ((Status == ERROR_SUCCESS) && (ValType == PCIBUS_SECONDARYLATENCY_VALTYPE)) {
        // Latency value exists
        pInfo->SecondaryLatency = Val;
    }
    
    RegCloseKey(Key);
    
    return TRUE;
}
//
// Get Prefetch Memory Window from registry.
//
BOOL    
RegGetExtraDeviceInfo(
    PPCI_DEV_INFO_EX pInfo
    )
{
    HKEY Key;
    DWORD Status;
    BOOL ConfigDllExists = TRUE;
    BOOL DllExists = TRUE;
    DWORD dwValType, ValLen;

    //
    // Open key to be enumerated
    //
    Status = RegOpenKeyEx(
                HKEY_LOCAL_MACHINE,
                pInfo->pciDevice.RegPath,
                0,
                0,
                &Key);
                
    if (Status != ERROR_SUCCESS) {
        DEBUGMSG(ZONE_ENUM|ZONE_ERROR,
            (TEXT("PCIBUS!RegGetExtraDeviceInfo RegOpenKeyEx(%s) returned %d.\r\n"),
            pInfo->pciDevice.RegPath, Status));
        return FALSE;
    }
    //
    // Read BusNumber Base and Length.
    //
    ValLen = sizeof(pInfo->dwBusNumberBase);
    if (RegQueryValueEx(Key, PCIBUS_BUSNUMBERBASE_VALNAME, NULL, &dwValType, (PBYTE)&(pInfo->dwBusNumberBase), &ValLen) == ERROR_SUCCESS && 
            dwValType == PCIBUS_BUSNUMBERBASE_VALTYPE ) {
        if (RegQueryValueEx(Key, PCIBUS_BUSNUMBERLENGTH_VALNAME, NULL, &dwValType, (PBYTE)&(pInfo->dwBusNumberLength), &ValLen) == ERROR_SUCCESS && 
                dwValType == PCIBUS_BUSNUMBERLENGTH_VALTYPE ) {
        }
        else {
            pInfo->dwBusNumberLength = PCI_MAX_BUS ;
        }
    }
    else {
        pInfo->dwBusNumberBase = 0;
        pInfo->dwBusNumberLength = PCI_MAX_BUS;
    }
    pInfo->dwBusNumberLength = min (pInfo->dwBusNumberLength, PCI_MAX_BUS);
    //
    // Read MemBase and MemLen values.
    //
    pInfo->PrefetchMemBase.Num = PCI_TYPE0_ADDRESSES;
    if (!RegGetList(Key, PCIBUS_PREFETCH_MEMBASE_VALNAME, &pInfo->PrefetchMemBase.Num, pInfo->PrefetchMemBase.Reg) && (pInfo->PrefetchMemBase.Num == PCI_TYPE0_ADDRESSES)) {
        DEBUGMSG(ZONE_WARNING, (L"PCIBUS!RegGetExtraDeviceInfo: Registry value '%s\\%s' has more than %d items in multi_sz list.  Ignoring the additional items.\r\n",
            pInfo->pciDevice.RegPath, PCIBUS_PREFETCH_MEMBASE_VALNAME, PCI_TYPE0_ADDRESSES));
    }

    pInfo->PrefetchMemLen.Num = PCI_TYPE0_ADDRESSES;
    if (!RegGetList(Key, PCIBUS_PREFETCH_MEMLEN_VALNAME, &pInfo->PrefetchMemLen.Num, pInfo->PrefetchMemLen.Reg) && (pInfo->PrefetchMemLen.Num == PCI_TYPE0_ADDRESSES)) {
        DEBUGMSG(ZONE_WARNING, (L"PCIBUS!RegGetExtraDeviceInfo: Registry value '%s\\%s' has more than %d items in multi_sz list.  Ignoring the additional items.\r\n",
            pInfo->pciDevice.RegPath, PCIBUS_PREFETCH_MEMLEN_VALNAME, PCI_TYPE0_ADDRESSES));
    }
    RegCloseKey(Key);    
    return TRUE;

}


//
// Get Flags value from registry.
//
static BOOL
RegGetFlags(
    PPCI_DEV_INFO pInfo 
    )
{
    HKEY Key;
    DWORD Status;
    DWORD ValLen, ValType, Val;
    
    //
    // Open key to be enumerated
    //
    Status = RegOpenKeyEx(
                HKEY_LOCAL_MACHINE,
                pInfo->RegPath,
                0,
                0,
                &Key);
                
    if (Status != ERROR_SUCCESS) {
        DEBUGMSG(ZONE_ENUM|ZONE_ERROR,
            (TEXT("PCIBUS!RegGetFlags RegOpenKeyEx(%s) returned %d.\r\n"),
            pInfo->RegPath, Status));
        return FALSE;
    }
    
    //
    // Read Flags value (if it exists)
    //
    ValLen = sizeof(pInfo->DevFlags);
    Status = RegQueryValueEx(Key, DEVLOAD_FLAGS_VALNAME, NULL, &ValType, (PUCHAR)&Val, &ValLen);            
    if ((Status == ERROR_SUCCESS) && (ValType == DEVLOAD_FLAGS_VALTYPE)) {
        // Flags value exists
        pInfo->DevFlags = Val;
    } else {
        pInfo->DevFlags = DEVFLAGS_NONE;
    }

    RegCloseKey(Key);
    
    return TRUE;
}


//
// Load configuration routine DLL and map entry point.
//
BOOL
LoadConfigEntry(
    PPCI_DEV_INFO pInfo
    )
{
    PFN_CONFIGENTRY ConfigEntryFn;
    HMODULE hDll;
    
    // If ConfigEntry, load config DLL and get ConfigEntry address
    if (pInfo->ConfigEntry) {
        if (pInfo->DevFlags & DEVFLAGS_LOADLIBRARY) {
           hDll = LoadLibrary(pInfo->ConfigDllName);
        } else {
           hDll = LoadDriver(pInfo->ConfigDllName);
        }

        if (hDll != NULL) {
            // Driver/library load successful, get ConfigEntry address
            ConfigEntryFn = (PFN_CONFIGENTRY)GetProcAddress(hDll, pInfo->ConfigEntryName);
            if (ConfigEntryFn == NULL) {
                DEBUGMSG(ZONE_ERROR, (L"PCIBUS!GetConfigEntry: GetProcAddr(%s, %s) failed with error %d.\r\n",
                    pInfo->DllName, pInfo->ConfigEntryName, GetLastError()));

                FreeLibrary(hDll);
                    
                goto GetConfigEntry_EXIT;
            }

            // Create ConfigInfo node and place into list
            pInfo->ConfigInfo = AddConfigInfo(hDll, ConfigEntryFn);
            if (pInfo->ConfigInfo == NULL) {
                DEBUGMSG(ZONE_ERROR, (L"PCIBUS!GetConfigEntry: AddConfigInfo( ) failed, out of memory.\r\n"));

                FreeLibrary(hDll);
                    
                goto GetConfigEntry_EXIT;
            }

            return TRUE;
        } else {
            // Driver/library load not successful, ConfigEntry becomes false
            DEBUGMSG(ZONE_ERROR, (L"PCIBUS!GetConfigEntry: LoadDriver/Library(%s) failed with error %d.\r\n", pInfo->ConfigDllName, GetLastError()));

            goto GetConfigEntry_EXIT;
        }
    } 
    
GetConfigEntry_EXIT:
    pInfo->ConfigEntry = FALSE;
    wcscpy(pInfo->ConfigEntryName, L"");
    wcscpy(pInfo->DllName, L"");
    pInfo->ConfigInfo = NULL;

    return FALSE;
}


//
// Unload configuration routine DLLs.
//
void
UnloadConfigEntrys(
    void
    )
{
    DelConfigInfoList( );
}


//
// Add configuration DLL handles to tracking list.
//
static PPCI_CFG_INFO
AddConfigInfo(
    HMODULE hDll,
    PFN_CONFIGENTRY ConfigEntryFn
    )
{
    PPCI_CFG_INFO ci = (PPCI_CFG_INFO)LocalAlloc(0, sizeof(PCI_CFG_INFO));

    if (!ci) return NULL;

    ci->hDll = hDll;
    ci->ConfigEntryFn = ConfigEntryFn;
    ci->Next = g_ConfigInfoList;

    g_ConfigInfoList = ci;
    
    return ci;
}


//
// Delete configuration DLL handles from tracking list and unload them.
//
static void
DelConfigInfoList(
    void
    )
{
    PPCI_CFG_INFO ni;
    PPCI_CFG_INFO ci = g_ConfigInfoList;
    
    while (ci) {
        ni = ci->Next;
        FreeLibrary(ci->hDll);
        LocalFree(ci);
        ci = ni;
    }

    g_ConfigInfoList = NULL;
}             


#ifdef DEBUG
#define DUMPPCICFG(X) { \
    if (ZONE_INIT) DumpPciConfig(X); \
}
#else
#define DUMPPCICFG(X) ((void)0)
#endif
BOOL IsSystemPhase1()
{
    HANDLE hEvent;
    static BOOL Phase1 = TRUE;

    // Find out whether or not we're in boot phase 1 or 2
    if ( Phase1 && (hEvent = OpenEvent(EVENT_ALL_ACCESS, FALSE, TEXT("SYSTEM/BootPhase2")))!=NULL) {
        if (WaitForSingleObject(hEvent, 0) == WAIT_OBJECT_0) {
            // We're in boot phase 2
            Phase1 = FALSE;
        }
        CloseHandle(hEvent);
    }
    return Phase1;
}

//
// Enumerate PCIbus.
//
static BOOL
PCIEnum(
    LPCWSTR EnumKey, DWORD dwBusNumberBase, DWORD dwBusNameLength
    )
{
    PCI_SLOT_NUMBER slotNumber;
    PCI_COMMON_CONFIG pciConfig;
    PCI_DEV_INFO Info;
    DWORD bus;
    int device, function;
    int length;
    BOOL Phase1 =  IsSystemPhase1();
    DEBUGMSG(ZONE_FUNCTION, (L"PCIBUS!PCIEnum(%s), Boot phase %d\r\n", EnumKey, (Phase1) ? 1 : 2));
    
    slotNumber.u.AsULONG = 0;
    
    // Scan bus
    for (bus = dwBusNumberBase; bus < dwBusNumberBase + dwBusNameLength; bus++) {
        for (device = 0; device < PCI_MAX_DEVICES; device++) {
            slotNumber.u.bits.DeviceNumber = device;

            for (function = 0; function < PCI_MAX_FUNCTION; function++) {
                slotNumber.u.bits.FunctionNumber = function;
                pciConfig.VendorID = 0xFFFF;
                pciConfig.HeaderType = 0;

                length = HalGetBusData(
                    PCIConfiguration,
                    bus,
                    slotNumber.u.AsULONG,
                    &pciConfig,
                    sizeof(pciConfig) - sizeof(pciConfig.DeviceSpecific)
                );

                if (length != (sizeof(pciConfig) - sizeof(pciConfig.DeviceSpecific)) ||
                    (pciConfig.DeviceID == PCI_INVALID_DEVICEID) || (pciConfig.VendorID == PCI_INVALID_VENDORID) || (pciConfig.VendorID == 0)) {
                    // No function found
                    if (function != 0) {
                        // If a multi-function device, continue to next function
                        continue;
                    } else {
                        // If not a multi-function device, continue to next device
                        break;
                    }
                }

                // Initialize out device info
                PCIInitInfo(EnumKey, bus, device, function, &pciConfig, &Info);

                // Get BAR length information, either from registry or from h/w
                PCIGetBARs(&Info);

                // Complete device's final initialization step (if it has one)

⌨️ 快捷键说明

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