📄 ohcd.c
字号:
/*++
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-1998 Microsoft Corporation
Module Name:
ohcd.c
Abstract:
Platform dependant part of the USB Open Host Controller Driver (OHCD).
Notes:
--*/
#include <windows.h>
#include <ceddk.h>
#include <nkintr.h>
//#include <oalintr.h>
#include <ohcdddsi.h>
#include "sa11x1.h"
//#include "sa11X0BD.h"
//#include "sa11x1db.h"
#include "macros.h"
// Registry key and value names
#define OHCI_DRIVER_KEY TEXT("Drivers\\BuiltIn\\OHCI")
#define USE_EXISTING_VALUE_NAME TEXT("UseExistingSettings")
#define IRQ_VALUE_NAME TEXT("Irq")
#define IOBASE_VALUE_NAME TEXT("MemBase")
extern void usWait(unsigned msVal);
// Amount of memory to use for HCD buffer
extern DWORD gcTotalAvailablePhysicalMemory;// = OHCI_DMA_BUFFER_SIZE; //28672; // 28K
extern DWORD gcHighPriorityPhysicalMemory;// = OHCI_DMA_BUFFER_HIGHPRI_SIZE; //0x5000; // 20K
extern DWORD dwSysIntrOhciMdd;//=SYSINTR_OHCI_MDD;
extern DWORD dwSysIntrOhciPdd;//=SYSINTR_OHCI_PDD
extern DWORD dwSKBase;//=SK_BA
//Dma Buffer
extern DWORD dwOhciDmaBufferPhysical;//=OHCI_DMA_BUFFER_PHYSICAL
extern PVOID pOhciDmaBufferVirtual;//=OHCI_DMA_BUFFER_U_VIRTUAL
extern DWORD dwOhciDmaBufferSize;//=OHCI_DMA_BUFFER_SIZE
// Daughter card register structures
volatile struct SK_IRQRegisterBlock *v_pDCIRQReg;
volatile struct SK_SC_PLLRegisterBlock *v_pDCPLLReg;
volatile struct SK_USBRegisterBlock *v_pDCUSBReg;
volatile struct SK_SMCRegisterBlock *v_pDCSMCReg;
PVOID v_pOHCIDMABuffer;
// Interrupt Service Thread Globals
VOID *gOHCIPDDIntrEvent;
VOID *gOHCIPDDIntrThread;
extern PVOID VirtualAllocCopy(unsigned size,char *str,PVOID pVirtualAddress);
extern VOID DriverSleep(DWORD, BOOL);
VOID OHCI_Reset(VOID);
BOOL OhcdPddInitializeAddresses( void );
typedef struct _SOhcdPdd
{
LPVOID lpvMemoryObject;
LPVOID lpvOhcdMddObject;
} SOhcdPdd;
#define UnusedParameter(x) x = x
/* OhcdPdd_DllMain
*
* DLL Entry point.
*
* Return Value:
*/
extern BOOL OhcdPdd_DllMain(HANDLE hinstDLL, DWORD dwReason, LPVOID lpvReserved)
{
UnusedParameter(hinstDLL);
UnusedParameter(dwReason);
UnusedParameter(lpvReserved);
return TRUE;
}
/* GetRegistryConfig
*
* Function to get the IRQ and I/O port range from the registry.
* Note: Will need to be changed to support multiple instances.
*
* Return Value:
* TRUE for success, FALSE for error
*/
/* GetRegistryConfig
*
* Function to get the IRQ and I/O port range from the registry.
* Note: Will need to be changed to support multiple instances.
*
* Return Value:
* TRUE for success, FALSE for error
*/
static BOOL
GetRegistryConfig(
DWORD * lpdwUseExistingSettings, // OUT- Receives value that indicates whether to
// just use the resources assigned by the BIOS.
DWORD * lpdwIrq, // OUT- Receives IRQ value
DWORD * lpdwIoBase) // OUT- Receives I/O base
{
HKEY hKey;
DWORD dwData;
DWORD dwSize;
DWORD dwType;
BOOL fRet=FALSE;
DWORD dwRet;
dwRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,OHCI_DRIVER_KEY,0,0,&hKey);
if (dwRet != ERROR_SUCCESS) {
DEBUGMSG(ZONE_ERROR,(TEXT("!OHCD:GetRegistryConfig RegOpenKeyEx(%s) failed %d\r\n"),
OHCI_DRIVER_KEY, dwRet));
return FALSE;
}
dwSize = sizeof(dwData);
dwRet = RegQueryValueEx(hKey,USE_EXISTING_VALUE_NAME,0,&dwType,(PUCHAR)&dwData,&dwSize);
if (dwRet != ERROR_SUCCESS) {
DEBUGMSG(ZONE_ERROR, (TEXT("!OHCD:GetRegistryConfig RegQueryValueEx(%s) failed %d\r\n"),
USE_EXISTING_VALUE_NAME, dwRet));
goto GetRegistryConfig_exit;
}
*lpdwUseExistingSettings = dwData;
dwSize = sizeof(dwData);
dwRet = RegQueryValueEx(hKey,IRQ_VALUE_NAME,0,&dwType,(PUCHAR)&dwData,&dwSize);
if (dwRet != ERROR_SUCCESS) {
DEBUGMSG(ZONE_ERROR, (TEXT("!OHCD:GetRegistryConfig RegQueryValueEx(%s) failed %d\r\n"),
IRQ_VALUE_NAME, dwRet));
goto GetRegistryConfig_exit;
}
*lpdwIrq = dwData;
dwSize = sizeof(dwData);
dwRet = RegQueryValueEx(hKey,IOBASE_VALUE_NAME,0,&dwType,(PUCHAR)&dwData,&dwSize);
if (dwRet != ERROR_SUCCESS) {
DEBUGMSG(ZONE_ERROR,(TEXT("!OHCD:GetRegistryConfig RegQueryValueEx(%s) failed %d\r\n"),
IOBASE_VALUE_NAME, dwRet));
goto GetRegistryConfig_exit;
}
*lpdwIoBase = dwData;
fRet = TRUE;
GetRegistryConfig_exit:
RegCloseKey(hKey);
return fRet;
} // GetRegistryConfig
/* SetRegistryConfig
*
* Function to set the IRQ and I/O port range in the registry.
* Note: Will need to be changed to support multiple instances.
*
* Return Value:
* TRUE for success, FALSE for error
*/
static BOOL
SetRegistryConfig(
DWORD dwIrq, // IN - IRQ value
DWORD dwIoBase) // IN - I/O base
{
HKEY hKey;
BOOL fRet=FALSE;
DWORD dwRet;
dwRet = RegOpenKeyEx(HKEY_LOCAL_MACHINE,OHCI_DRIVER_KEY,0,0,&hKey);
if (dwRet != ERROR_SUCCESS) {
DEBUGMSG(ZONE_ERROR,(TEXT("!OHCD:SetRegistryConfig RegOpenKeyEx(%s) failed %d\r\n"),
OHCI_DRIVER_KEY, dwRet));
return FALSE;
}
dwRet = RegSetValueEx(hKey,IRQ_VALUE_NAME,0,REG_DWORD,(PUCHAR)&dwIrq,sizeof(DWORD));
if (dwRet != ERROR_SUCCESS) {
DEBUGMSG(ZONE_ERROR, (TEXT("!OHCD:SetRegistryConfig RegQueryValueEx(%s) failed %d\r\n"),
IRQ_VALUE_NAME, dwRet));
goto SetRegistryConfig_exit;
}
dwRet = RegSetValueEx(hKey,IOBASE_VALUE_NAME,0,REG_DWORD,(PUCHAR)&dwIoBase,sizeof(DWORD));
if (dwRet != ERROR_SUCCESS) {
DEBUGMSG(ZONE_ERROR,(TEXT("!OHCD:SetRegistryConfig RegQueryValueEx(%s) failed %d\r\n"),
IOBASE_VALUE_NAME, dwRet));
goto SetRegistryConfig_exit;
}
fRet = TRUE;
SetRegistryConfig_exit:
RegCloseKey(hKey);
return fRet;
} // SetRegistryConfig
/* 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
{
DWORD dwUseExistingSettings;
PUCHAR ioPortBase = NULL;
DWORD dwSysIntr;
BOOL fResult = FALSE;
LPVOID pobMem = NULL;
LPVOID pobOhcd = NULL;
OHCI_Reset();
if (!GetRegistryConfig(&dwUseExistingSettings, &dwSysIntr, (DWORD *)&ioPortBase)) {
RETAILMSG(1,(TEXT("!OHCD: Error reading registry settings\r\n")));
return FALSE;
}
DEBUGMSG(ZONE_INIT,(TEXT("OHCD: Read config from registry: Use existing: %u, IRQ: %u, I/O base: %X\r\n"),
dwUseExistingSettings,dwSysIntr,ioPortBase));
if (dwUseExistingSettings) {
dwSysIntr = dwSysIntrOhciMdd;//SYSINTR_OHCI_MDD;
ioPortBase = (PUCHAR) v_pDCUSBReg->Revision;
DEBUGMSG(ZONE_INIT,(TEXT("OHCD: Set registry: IRQ: %u, I/O base: %X\r\n"), dwSysIntr,ioPortBase));
SetRegistryConfig(dwSysIntr, (DWORD)ioPortBase);
}
fResult = TRUE;
//temp hack to get around registry
ioPortBase = (PUCHAR) v_pDCUSBReg->Revision;
dwSysIntr = dwSysIntrOhciMdd;//SYSINTR_OHCI_MDD;
if(fResult)
{
// 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, let the MDD do it.
// Above comment came from CEPC OHCI driver, we found the letting the MDD allocate th
// memory did not work
pobMem = OhcdMdd_CreateMemoryObject(gcTotalAvailablePhysicalMemory,
gcHighPriorityPhysicalMemory, (PUCHAR) v_pOHCIDMABuffer, (PUCHAR)dwOhciDmaBufferPhysical/* OHCI_DMA_BUFFER_PHYSICAL*/);
if(pobMem)
{
// Pass the MDD SYSINTR it will hook it in and presumably call OEMinterrupt_init etc
DEBUGMSG(ZONE_INIT,(TEXT("OHCD: SYSINTR_OHCI_MDD: %u\r\n"), dwSysIntrOhciMdd/*SYSINTR_OHCI_MDD*/));
NKDbgPrintfW(TEXT("OHCIPdd Init OHCI CreateOBject +\r\n"));
pobOhcd = OhcdMdd_CreateOhcdObject(pPddObject, pobMem, szDriverRegKey, ioPortBase, dwSysIntr);
fResult = pobOhcd ? TRUE : FALSE;
}
else
fResult = FALSE;
if(!fResult)
{
if(pobOhcd)
OhcdMdd_DestroyOhcdObject(pobOhcd);
if(pobMem)
OhcdMdd_DestroyMemoryObject(pobMem);
pobOhcd = NULL;
pobMem = NULL;
}
}
pPddObject->lpvMemoryObject = pobMem;
pPddObject->lpvOhcdMddObject = pobOhcd;
return fResult;
}
INT WINAPI OHCIPDDIntrThread(
)
{
while (1) {
WaitForSingleObject(gOHCIPDDIntrEvent, INFINITE);
//See which SA-1111 non-OHCI Controller interrupt we got
//DEBUGMSG(ZONE_INIT, (TEXT("OHCIPDD INTR Thread Interrupt Event\r\n")));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -