📄 system.c
字号:
//
// 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.
//
/*++
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.
Module Name:
system.c
Abstract:
Device dependant part of the USB Universal Host Controller Driver (UHCD).
Notes:
--*/
#include <windows.h>
#include <nkintr.h>
#include <ceddk.h>
#include <devload.h>
#include <giisr.h>
#include <uhcdddsi.h>
// Amount of memory to use for HCD buffer
static const DWORD gcTotalAvailablePhysicalMemory = 65536; // 64K
static const DWORD gcHighPriorityPhysicalMemory = 0x4000; // 16K
static HANDLE g_IsrHandle = NULL;
typedef struct _SUhcdPdd
{
LPVOID lpvMemoryObject;
LPVOID lpvUhcdMddObject;
PVOID pvVirtualAddress; // DMA buffers as seen by the CPU
PHYSICAL_ADDRESS LogicalAddress; // DMA buffers as seen by the DMA controller and bus interfaces
DMA_ADAPTER_OBJECT AdapterObject;
TCHAR szDriverRegKey[MAX_PATH];
PUCHAR ioPortBase;
DWORD dwSysIntr;
CRITICAL_SECTION csPdd; // serializes access to the PDD object
} SUhcdPdd;
#define UnusedParameter(x) x = x
/* HcdPdd_DllMain
*
* DLL Entry point.
*
* Return Value:
*/
extern BOOL HcdPdd_DllMain(HANDLE hinstDLL, DWORD dwReason, LPVOID lpvReserved)
{
UnusedParameter(hinstDLL);
UnusedParameter(dwReason);
UnusedParameter(lpvReserved);
return TRUE;
}
/* GetRegistryConfig
*
* Note: Will need to be changed to support multiple instances.
*
* Return Value:
* TRUE for success, FALSE for error
*/
static BOOL
GetRegistryConfig(
LPCWSTR RegKeyPath, // IN - driver registry key path
DWORD * lpdwBaseAddr, // OUT - base address
DWORD * lpdwAddrLen, // OUT - address range
DWORD * lpdwIOSpace, // OUT - 1 if base address describes I/O port, 0 otherwise
DWORD * lpdwSysIntr, // OUT - system interrupt number
PINTERFACE_TYPE lpIfcType, // OUT - interface type (PCIbus, ISAbus, etc)
DWORD * lpdwBusNumber, // OUT - bus number, depends on interface type
BOOL * bInstallIsr, // OUT - TRUE if ISR Handler found in registry
LPWSTR IsrDll, // OUT - Name of ISR Handler dll
LPWSTR IsrHandler, // OUT - Name of ISR Handler routine
DWORD * Irq // OUT - IRQ number, used to hook ISR handler
)
{
HKEY hKey;
DWORD dwData;
DWORD dwSize;
DWORD dwType;
BOOL fRet=FALSE;
DWORD dwRet;
const USHORT cDefaultUhcdPortRange = 0x20;
const ULONG cHTBAMemorySpace = 0;
const ULONG cHTBAIOSpace = 1;
// Open key
dwRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,RegKeyPath,0,0,&hKey);
if (dwRet != ERROR_SUCCESS) {
DEBUGMSG(ZONE_ERROR,(TEXT("!UHCD:GetRegistryConfig RegOpenKeyEx(%s) failed %d\r\n"),
RegKeyPath, dwRet));
return FALSE;
}
// Read base address, range from registry and determine IOSpace
dwSize = sizeof(dwData);
dwRet = RegQueryValueEx(hKey, DEVLOAD_MEMBASE_VALNAME, 0, &dwType, (PUCHAR)&dwData, &dwSize);
if (dwRet == ERROR_SUCCESS) {
*lpdwIOSpace = cHTBAMemorySpace;
*lpdwBaseAddr = dwData;
dwRet = RegQueryValueEx(hKey, DEVLOAD_MEMLEN_VALNAME, 0, &dwType, (PUCHAR)&dwData, &dwSize);
if (dwRet == ERROR_SUCCESS) {
*lpdwAddrLen = dwData;
} else {
*lpdwAddrLen = cDefaultUhcdPortRange;
}
} else {
dwRet = RegQueryValueEx(hKey,DEVLOAD_IOBASE_VALNAME,0,&dwType,(PUCHAR)&dwData,&dwSize);
if (dwRet != ERROR_SUCCESS) {
DEBUGMSG(ZONE_ERROR, (TEXT("!UHCD:GetRegistryConfig Neither %s nor %s were found.\r\n"),
DEVLOAD_MEMBASE_VALNAME, DEVLOAD_IOBASE_VALNAME, dwRet));
goto GetRegistryConfig_exit;
}
*lpdwIOSpace = cHTBAIOSpace;
*lpdwBaseAddr = dwData;
dwRet = RegQueryValueEx(hKey,DEVLOAD_IOLEN_VALNAME,0,&dwType,(PUCHAR)&dwData,&dwSize);
if (dwRet == ERROR_SUCCESS) {
*lpdwAddrLen = dwData;
} else {
*lpdwAddrLen = cDefaultUhcdPortRange;
}
}
// Read SysIntr from registry
dwSize = sizeof(dwData);
dwRet = RegQueryValueEx(hKey,DEVLOAD_SYSINTR_VALNAME,0,&dwType,(PUCHAR)&dwData,&dwSize);
if (dwRet != ERROR_SUCCESS) {
DEBUGMSG(ZONE_ERROR, (TEXT("!UHCD:GetRegistryConfig RegQueryValueEx(%s) failed %d\r\n"),
DEVLOAD_SYSINTR_VALNAME, dwRet));
goto GetRegistryConfig_exit;
}
*lpdwSysIntr = dwData;
// Read interface type from registry
dwSize = sizeof(dwData);
dwRet = RegQueryValueEx(hKey,DEVLOAD_IFCTYPE_VALNAME,0,&dwType,(PUCHAR)&dwData,&dwSize);
if (dwRet != ERROR_SUCCESS) {
// Default value is PCIBus
*lpIfcType = PCIBus;
} else {
*lpIfcType = dwData;
}
// Read bus number from registry
dwSize = sizeof(dwData);
dwRet = RegQueryValueEx(hKey,DEVLOAD_BUSNUMBER_VALNAME,0,&dwType,(PUCHAR)&dwData,&dwSize);
if (dwRet != ERROR_SUCCESS) {
// Default value is 0
*lpdwBusNumber = 0;
} else {
*lpdwBusNumber = dwData;
}
// Read installable ISR dll name from registry, if it exists
dwSize = DEVDLL_LEN * sizeof(WCHAR);
dwRet = RegQueryValueEx(hKey, DEVLOAD_ISRDLL_VALNAME, 0, &dwType, (PUCHAR)IsrDll, &dwSize);
if (dwRet == ERROR_SUCCESS) {
// ISR dll name found, now look for ISR handler routine name
dwSize = DEVENTRY_LEN * sizeof(WCHAR);
dwRet = RegQueryValueEx(hKey, DEVLOAD_ISRHANDLER_VALNAME, 0, &dwType, (PUCHAR)IsrHandler, &dwSize);
if (dwRet == ERROR_SUCCESS) {
// ISR handler name found, now look for Irq
dwSize = sizeof(dwData);
dwRet = RegQueryValueEx(hKey, DEVLOAD_IRQ_VALNAME, 0, &dwType, (PUCHAR)&dwData, &dwSize);
if (dwRet == ERROR_SUCCESS) {
*Irq = dwData;
*bInstallIsr = TRUE;
} else {
DEBUGMSG(ZONE_WARNING, (L"!UHCD: Registry values %s and %s found, but no corresponding value %s found\r\n",
DEVLOAD_ISRDLL_VALNAME, DEVLOAD_ISRHANDLER_VALNAME, DEVLOAD_IRQ_VALNAME));
}
} else {
DEBUGMSG(ZONE_WARNING, (L"!UHCD: Registry value %s found, but no corresponding value %s found\r\n",
DEVLOAD_ISRDLL_VALNAME, DEVLOAD_ISRHANDLER_VALNAME));
}
}
fRet = TRUE;
GetRegistryConfig_exit:
RegCloseKey(hKey);
return fRet;
} // GetRegistryConfig
/* ConfigureUHCICard
*
*/
BOOL
ConfigureUHCICard(
PUCHAR *pioPortBase, // IN - contains physical address of register base
// OUT- contains virtual address of register base
DWORD dwAddrLen,
DWORD dwIOSpace,
INTERFACE_TYPE IfcType,
DWORD dwBusNumber
)
{
ULONG inIoSpace = dwIOSpace;
ULONG portBase;
PHYSICAL_ADDRESS ioPhysicalBase = {0, 0};
portBase = (ULONG)*pioPortBase;
ioPhysicalBase.LowPart = portBase;
if (!TransBusAddrToVirtual(IfcType, dwBusNumber, ioPhysicalBase, dwAddrLen, &inIoSpace, (PPVOID)pioPortBase)) {
DEBUGMSG(ZONE_ERROR, (L"UHCD: Failed TransBusAddrToVirtual\r\n"));
return FALSE;
}
DEBUGMSG(ZONE_INIT,
(TEXT("UHCD: ioPhysicalBase 0x%X, IoSpace 0x%X\r\n"),
ioPhysicalBase.LowPart, inIoSpace));
DEBUGMSG(ZONE_INIT,
(TEXT("UHCD: ioPortBase 0x%X, portBase 0x%X\r\n"),
*pioPortBase, portBase));
return TRUE;
}
/* InitializeUHCI
*
* Configure and initialize UHCI card
*
* Return Value:
* Return TRUE if card could be located and configured, otherwise FALSE
*/
static BOOL
InitializeUHCI(
SUhcdPdd * pPddObject, // IN - Pointer to PDD structure
LPCWSTR szDriverRegKey) // IN - Pointer to active registry key string
{
PUCHAR ioPortBase = NULL;
DWORD dwAddrLen;
DWORD dwIOSpace;
DWORD dwSysIntr;
INTERFACE_TYPE IfcType;
DWORD dwBusNumber;
BOOL InstallIsr = FALSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -