📄 system.c
字号:
//
// Copyright (c) Renesas Technology Corp. 2003. All Rights Reserved.
// USB OHCI Host Controller Driver
//
// FILE : SYSTEM.C
// CREATED : 2002. 6. 7 (sample code in Platform Builder 4.1)
// MODIFIED : 2003. 6. 9
// AUTHOR : Renesas Technology Corp.
// HARDWARE : HS7751RSTC01H (S1-E, ITS-DS5)
// US7760-HRP10E (Biscayne, ITS-DS6)
// TARGET OS : Microsoft(R) Windows(R) CE .NET 4.2
// FUNCTIONS : USB OHCI host controller PDD for Renesas USB Host core
// HISTORY :
// 2003. 2.20
// - USB OHCI sample PDD in Platform Builder 4.1 is initially
// modified for US7760-HRP10E.
// - Parameters are fixed and PCI related codes are removed.
// 2003. 3. 9
// - Hardware parameter is changed to be read from registry to
// support different platform.
//----------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
#include <windows.h>
#include <uhcdddsi.h>
// Amount of memory to use for HCD buffer
DWORD g_dwTotalAvailablePhysicalMemory;
DWORD g_dwHighPriorityPhysicalMemory;
static HANDLE g_IsrHandle = NULL;
typedef struct _SOhcdPdd
{
PVOID pvMemoryObject;
PVOID pvOhcdMddObject;
PVOID pvVirtualAddress; // register base
PVOID pvMemBase; // Host controller RAM area
PUCHAR ioPortBase;
CRITICAL_SECTION csPdd; // serializes access to the PDD object
} SOhcdPdd;
#define UnusedParameter(x) x = x
#define ALLOC_PAGE_SIZE 4096
/* 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 * lpdwRegBase, // OUT - register base address
DWORD * lpdwMemBase, // OUT - shared memory base address
DWORD * lpdwHWMemBase, // OUT - shared memory address for hardware
DWORD * lpdwTotalMemSize, // OUT - total shared memory size
DWORD * lpdwHiPrioMemSize, // OUT - high priority memory size
DWORD * lpdwSysIntr // OUT - system interrupt number
)
{
HKEY hKey;
DWORD dwData;
DWORD dwSize;
DWORD dwType;
DWORD dwRet;
// Open key
dwRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,RegKeyPath,0,0,&hKey);
if (dwRet != ERROR_SUCCESS) {
RETAILMSG(1,
(TEXT("!OHCD:GetRegistryConfig RegOpenKeyEx(%s) failed %d\r\n"),
RegKeyPath, dwRet));
return FALSE;
}
dwSize = sizeof(dwData);
// Read register base address
dwRet = RegQueryValueEx(hKey, TEXT("RegBase"), 0, &dwType,
(PUCHAR)&dwData, &dwSize);
if (dwRet == ERROR_SUCCESS) {
*lpdwRegBase = dwData;
DEBUGMSG(1,
(TEXT("OHCD: RegBase = %08x.\r\n"), *lpdwRegBase));
}
else {
RETAILMSG(1,
(TEXT("!OHCD: RegBase not found in registry.\r\n")));
return FALSE;
}
// Read OHCI shared memory base address
dwRet = RegQueryValueEx(hKey, TEXT("MemBase"), 0, &dwType,
(PUCHAR)&dwData, &dwSize);
if (dwRet == ERROR_SUCCESS) {
*lpdwMemBase = dwData;
DEBUGMSG(1,
(TEXT("OHCD: MemBase = %08x.\r\n"), *lpdwMemBase));
}
else {
RETAILMSG(1,
(TEXT("!OHCD: MemBase not found in registry.\r\n")));
return FALSE;
}
// Read shared memory base address for host controller hardware
dwRet = RegQueryValueEx(hKey, TEXT("HWMemBase"), 0, &dwType,
(PUCHAR)&dwData, &dwSize);
if (dwRet == ERROR_SUCCESS) {
*lpdwHWMemBase = dwData;
DEBUGMSG(1,
(TEXT("OHCD: HWMemBase = %08x.\r\n"), *lpdwHWMemBase));
}
else {
RETAILMSG(1,
(TEXT("!OHCD: HWMemBase not found in registry.\r\n")));
return FALSE;
}
// Read total shared memory size
dwRet = RegQueryValueEx(hKey, TEXT("TotalMemSize"), 0, &dwType,
(PUCHAR)&dwData, &dwSize);
if (dwRet == ERROR_SUCCESS) {
*lpdwTotalMemSize = dwData;
DEBUGMSG(1,
(TEXT("OHCD: TotalMemSize = %08x.\r\n"), *lpdwTotalMemSize));
}
else {
RETAILMSG(1,
(TEXT("!OHCD: TotalMemSize not found in registry.\r\n")));
return FALSE;
}
// Read high priority shared memory size
dwRet = RegQueryValueEx(hKey, TEXT("HiPrioMemSize"), 0, &dwType,
(PUCHAR)&dwData, &dwSize);
if (dwRet == ERROR_SUCCESS) {
*lpdwHiPrioMemSize = dwData;
DEBUGMSG(1,
(TEXT("OHCD: HiPrioMemSize = %08x.\r\n"), *lpdwHiPrioMemSize));
}
else {
RETAILMSG(1,
(TEXT("!OHCD: HiPrioMemSize is not found in registry.\r\n")));
return FALSE;
}
// Read SysIntr from registry
dwRet = RegQueryValueEx(hKey, TEXT("SysIntr"), 0 , &dwType,
(PUCHAR)&dwData,&dwSize);
if (dwRet == ERROR_SUCCESS) {
*lpdwSysIntr = dwData;
DEBUGMSG(1,
(TEXT("OHCD: SysIntr = %d.\r\n"), *lpdwSysIntr));
}
else {
RETAILMSG(1,
(TEXT("!OHCD: SysIntr is not found in registry.\r\n")));
return FALSE;
}
return TRUE;
} // GetRegistryConfig
/* InitializeOHCI
*
* Configure and initialize OHCI card
*
* Return Value:
* Return TRUE if card could be located and configured, otherwise FALSE
*/
static BOOL
InitializeOHCI(
SOhcdPdd * pPddObject, // IN - Pointer to PDD structure
LPCWSTR szDriverRegKey) // IN - Pointer to active registry key string
{
LPVOID pobMem = NULL;
LPVOID pobOhcd = NULL;
LPVOID pvUsbRegister;
LPVOID pvUsbHcca;
DWORD dwRegAddr;
DWORD dwMemAddr;
DWORD dwHWMemBase;
DWORD dwBase;
DWORD dwOffset;
DWORD dwTotalMemSize;
DWORD dwHiPrioMemSize;
DWORD dwSysIntr;
if (!GetRegistryConfig(
szDriverRegKey,
&dwRegAddr,
&dwMemAddr,
&dwHWMemBase,
&dwTotalMemSize,
&dwHiPrioMemSize,
&dwSysIntr)) {
RETAILMSG(1,
(TEXT("!OHCD: Error reading registry settings\r\n")));
return FALSE;
}
// Adjust 4kB page boundary for USB registers
dwBase = dwRegAddr & ~(ALLOC_PAGE_SIZE - 1);
dwOffset = dwRegAddr & (ALLOC_PAGE_SIZE - 1);
// Allocate and map vertual address for USB registers
pPddObject->pvVirtualAddress = VirtualAlloc(
0, ALLOC_PAGE_SIZE, MEM_RESERVE, PAGE_NOACCESS);
if (pPddObject->pvVirtualAddress == NULL) {
RETAILMSG(1,
(TEXT("InitializeOHCI: VirtualAlloc (register) failed!\r\n")));
goto error_return;
}
if (!VirtualCopy(pPddObject->pvVirtualAddress,
(LPVOID)dwBase, ALLOC_PAGE_SIZE, PAGE_READWRITE|PAGE_NOCACHE)) {
RETAILMSG(1,
(TEXT("InitializeOHCI: VirtualCopy (register) failed!\r\n")));
goto error_return;
}
pvUsbRegister = (PVOID)(
(DWORD)pPddObject->pvVirtualAddress + dwOffset);
// Allocate and map vertual address for USB shared memory
// Shared memory address is not adjusted so it must be aligned in 4kB.
pPddObject->pvMemBase = VirtualAlloc(
0, dwTotalMemSize, MEM_RESERVE, PAGE_NOACCESS);
if (pPddObject->pvMemBase == NULL) {
RETAILMSG(1,
(TEXT("InitializeOHCI: VirtualAlloc (memory) failed!\r\n")));
goto error_return;
}
if (!VirtualCopy(pPddObject->pvMemBase,
(LPVOID)dwMemAddr, dwTotalMemSize, PAGE_READWRITE|PAGE_NOCACHE)) {
RETAILMSG(1,
(TEXT("InitializeOHCI: VirtualCopy (memory) failed!\r\n")));
goto error_return;
}
g_dwTotalAvailablePhysicalMemory = dwTotalMemSize;
g_dwHighPriorityPhysicalMemory = dwHiPrioMemSize;
// Shared memory base address for host controller hardware may take the
// value 0 but this causes problem. If this is set to 0, replaced it with
// 0x10000000. These higher bits are ignored by hardware.
if (dwHWMemBase == 0) dwHWMemBase = 0x10000000;
// The PDD can supply a buffer of contiguous physical memory here, or can
// let the MDD try to allocate the memory from system RAM.
// In our case, PDD supplies it.
pvUsbHcca = pPddObject->pvMemBase;
pobMem = HcdMdd_CreateMemoryObject(dwTotalMemSize,
dwHiPrioMemSize, pvUsbHcca, (PVOID)dwHWMemBase);
if (pobMem) {
pobOhcd = HcdMdd_CreateHcdObject(pPddObject, pobMem,
szDriverRegKey, pvUsbRegister, dwSysIntr);
if (!pobOhcd) {
RETAILMSG(1,
(TEXT("InitializeOHCI: HcdMdd_CreateHcdObject failed!\r\n")));
goto error_return;
}
}
pPddObject->pvMemoryObject = pobMem;
pPddObject->pvOhcdMddObject = pobOhcd;
return TRUE;
error_return:
if (pobOhcd) HcdMdd_DestroyHcdObject(pobOhcd);
if (pobMem) HcdMdd_DestroyMemoryObject(pobMem);
if (pPddObject->pvMemBase)
VirtualFree(pPddObject->pvMemBase, 0, MEM_RELEASE);
if (pPddObject->pvVirtualAddress)
VirtualFree(pPddObject->pvVirtualAddress, 0, MEM_RELEASE);
pPddObject->pvMemoryObject = NULL;
pPddObject->pvOhcdMddObject = NULL;
return FALSE;
}
/* HcdPdd_Init
*
* PDD Entry point - called at system init to detect and configure UHCI card.
*
* Return Value:
* Return pointer to PDD specific data structure, or NULL if error.
*/
extern DWORD
HcdPdd_Init(
DWORD dwContext) // IN - Pointer to context value. For device.exe, this is a string
// indicating our active registry key.
{
SOhcdPdd * pPddObject = malloc(sizeof(SOhcdPdd));
BOOL fRet = FALSE;
if (pPddObject) {
pPddObject->pvVirtualAddress = NULL;
InitializeCriticalSection(&pPddObject->csPdd);
fRet = InitializeOHCI(pPddObject, (LPCWSTR)dwContext);
if(!fRet)
{
free(pPddObject);
pPddObject = NULL;
}
}
return (DWORD)pPddObject;
}
/* HcdPdd_CheckConfigPower
*
* Check power required by specific device configuration and return whether it
* can be supported on this platform. For CEPC, this is trivial, just limit to
* the 500mA requirement of USB. For battery powered devices, this could be
* more sophisticated, taking into account current battery status or other info.
*
* Return Value:
* Return TRUE if configuration can be supported, FALSE if not.
*/
extern BOOL HcdPdd_CheckConfigPower(
UCHAR bPort, // IN - Port number
DWORD dwCfgPower, // IN - Power required by configuration
DWORD dwTotalPower) // IN - Total power currently in use on port
{
return ((dwCfgPower + dwTotalPower) > 500) ? FALSE : TRUE;
}
extern void HcdPdd_PowerUp(DWORD hDeviceContext)
{
SOhcdPdd * pPddObject = (SOhcdPdd *)hDeviceContext;
HcdMdd_PowerUp(pPddObject->pvOhcdMddObject);
return;
}
extern void HcdPdd_PowerDown(DWORD hDeviceContext)
{
SOhcdPdd * pPddObject = (SOhcdPdd *)hDeviceContext;
HcdMdd_PowerDown(pPddObject->pvOhcdMddObject);
return;
}
extern BOOL HcdPdd_Deinit(DWORD hDeviceContext)
{
SOhcdPdd * pPddObject = (SOhcdPdd *)hDeviceContext;
if(pPddObject->pvOhcdMddObject)
HcdMdd_DestroyHcdObject(pPddObject->pvOhcdMddObject);
if(pPddObject->pvMemoryObject)
HcdMdd_DestroyMemoryObject(pPddObject->pvMemoryObject);
if(pPddObject->pvVirtualAddress)
VirtualFree(pPddObject->pvVirtualAddress, 0, MEM_RELEASE);
return TRUE;
}
extern DWORD HcdPdd_Open(DWORD hDeviceContext, DWORD AccessCode,
DWORD ShareMode)
{
UnusedParameter(hDeviceContext);
UnusedParameter(AccessCode);
UnusedParameter(ShareMode);
return 1; // we can be opened, but only once!
}
extern BOOL HcdPdd_Close(DWORD hOpenContext)
{
UnusedParameter(hOpenContext);
return TRUE;
}
extern DWORD HcdPdd_Read(DWORD hOpenContext, LPVOID pBuffer, DWORD Count)
{
UnusedParameter(hOpenContext);
UnusedParameter(pBuffer);
UnusedParameter(Count);
return (DWORD)-1; // an error occured
}
extern DWORD HcdPdd_Write(DWORD hOpenContext, LPCVOID pSourceBytes,
DWORD NumberOfBytes)
{
UnusedParameter(hOpenContext);
UnusedParameter(pSourceBytes);
UnusedParameter(NumberOfBytes);
return (DWORD)-1;
}
extern DWORD HcdPdd_Seek(DWORD hOpenContext, LONG Amount, DWORD Type)
{
UnusedParameter(hOpenContext);
UnusedParameter(Amount);
UnusedParameter(Type);
return (DWORD)-1;
}
extern BOOL HcdPdd_IOControl(DWORD hOpenContext, DWORD dwCode, PBYTE pBufIn,
DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut, PDWORD pdwActualOut)
{
UnusedParameter(hOpenContext);
UnusedParameter(dwCode);
UnusedParameter(pBufIn);
UnusedParameter(dwLenIn);
UnusedParameter(pBufOut);
UnusedParameter(dwLenOut);
UnusedParameter(pdwActualOut);
return FALSE;
}
// Manage WinCE suspend/resume events
// This gets called by the MDD's IST when it detects a power resume.
// By default it has nothing to do.
extern void HcdPdd_InitiatePowerUp (DWORD hDeviceContext)
{
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -