📄 ohcd.c
字号:
if (v_pDCUSBReg->ussr[0].irqHciRmtWkp) {
RETAILMSG(1, (TEXT("OHCIPdd Int Thread Remote Wakeup Event\r\n")));
}
else if (v_pDCUSBReg->ussr[0].irqHciBuffAcc) {
RETAILMSG(1, (TEXT("OHCIPdd Int Thread Buffer Active Event\r\n")));
}
else if (v_pDCUSBReg->ussr[0].nIrqHciM) {
RETAILMSG(1, (TEXT("OHCIPdd Int Thread Normal HC Interrupt Event\r\n")));
}
else if (v_pDCUSBReg->ussr[0].nHciMFCir) {
RETAILMSG(1, (TEXT("OHCIPdd Int Thread Clear Signals Event\r\n")));
}
else if (v_pDCUSBReg->ussr[0].usbPwrSense) {
RETAILMSG(1, (TEXT("OHCIPdd Int Thread Power Sense Event\r\n")));
//if the USB clock is on go through reset sequence to start up the USB
// otherwise let normal HC int process
}
else {
RETAILMSG(1, (TEXT("OHCIPdd Int Thread No known Event\r\n")));
}
//Right now only Port Resume interrupts are enabled
if (!v_pDCPLLReg->skpcr[0].UCLKEn) {
RETAILMSG(1, (TEXT("OHCIPdd Int Port Resume, reseting Sense Event\r\n")));
OHCI_Reset();
}
//DEBUGMSG(ZONE_INIT, (TEXT("OHCI PDD INTR Thread called P\r\n")));
InterruptDone(dwSysIntrOhciPdd/*SYSINTR_OHCI_PDD*/);
}
}
/* OhcdPdd_Init
*
* PDD Entry point - called at system init to detect and configure OHCI card.
*
* Return Value:
* Return pointer to PDD specific data structure, or NULL if error.
*/
extern DWORD
OhcdPdd_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;
// Allocate Daughter Card PLL control USB Registers
DEBUGMSG(ZONE_INIT, (TEXT("+OHCI PDD Init\r\n")));
if ( !OhcdPddInitializeAddresses() ) {
return FALSE;
}
// This PDD will set up two interrupt service threads,
// first we create a thread to service the SA-1111 non-OHCI host controller interrupts
// Then in InitializeOHCI we hook the SA-1111 OHCI host controller interrupt in to the MDD
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
gOHCIPDDIntrEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (!(InterruptInitialize(dwSysIntrOhciPdd/*SYSINTR_OHCI_PDD*/, gOHCIPDDIntrEvent, NULL, 0))) {
DEBUGMSG(ZONE_INIT, (TEXT("OHCI PDD INTR INIT Failed\r\n")));
DEBUGMSG(ZONE_INIT, (TEXT("OHCI PDD INTR INIT ERR: 0x%x\r\r"), GetLastError()));
//return NULL;
return FALSE;
}
gOHCIPDDIntrThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) OHCIPDDIntrThread, NULL, 0, NULL);
if ( gOHCIPDDIntrThread == NULL ) {
DEBUGMSG(1, (TEXT("Fatal Error! Failed to create OHCIPDD Intterupt thread.\r\n")));
NKDbgPrintfW(TEXT("OHCIPddInit Failed to create OHCIPDD Intterupt thread\r\n"));
//return (NULL);
return (FALSE);
} else {
DEBUGMSG(ZONE_INIT, (TEXT("-OHCIPDD Init\r\n")));
//return TRUE;
}
RETAILMSG(1, (TEXT("OHCIPddInit RhPortStatus: 0x%x.\r\n"), v_pDCUSBReg->RhPortStatus[0]));
NKDbgPrintfW(TEXT("OHCIPddInit trying to init object\r\n"));
fRet = InitializeOHCI(pPddObject, (LPCWSTR)dwContext);
if(!fRet)
{
NKDbgPrintfW(TEXT("OHCIPddInit Failed to init object\r\n"));
free(pPddObject);
pPddObject = NULL;
}
return (DWORD)pPddObject;
}
BOOL
OhcdPddInitializeAddresses(
void
)
{
v_pDCUSBReg = (volatile struct SK_USBRegisterBlock *)
VirtualAllocCopy(SK_USB_HCI_SPACE,"OHCI v_pDCUSBReg: ",(PVOID)(dwSKBase +USB_BASE));
if (v_pDCUSBReg == NULL) {
goto error_return;
}
v_pDCPLLReg = (volatile struct SK_SC_PLLRegisterBlock *)
VirtualAllocCopy(SK_SC_PLL_SPACE,"OHCI v_pDCPLLReg: ",(PVOID)(dwSKBase + SK_PLL_BASE));
if (v_pDCPLLReg == NULL) {
goto error_return;
}
v_pDCIRQReg = (volatile struct SK_IRQRegisterBlock *)
VirtualAllocCopy(SK_IRQ_SPACE,"OHCI v_pDCIRQReg",(PVOID)(dwSKBase + SK_IRQ_BASE));
if (v_pDCIRQReg == NULL) {
goto error_return;
}
v_pDCSMCReg = (volatile struct SK_SMCRegisterBlock *)
VirtualAllocCopy(SK_SMC_SPACE,"OHCI v_pDCSMCReg",(PVOID)(dwSKBase + SMC_BASE));
if (v_pDCSMCReg == NULL) {
goto error_return;
}
v_pOHCIDMABuffer =
// VirtualAllocCopy(OHCI_DMA_BUFFER_SIZE,"OHCI v_pOHCIDMABuffer", (PVOID) OHCI_DMA_BUFFER_U_VIRTUAL);
VirtualAllocCopy(dwOhciDmaBufferSize,"OHCI v_pOHCIDMABuffer", pOhciDmaBufferVirtual);
if (v_pOHCIDMABuffer == NULL) {
goto error_return;
}
return TRUE;
error_return:
NKDbgPrintfW(TEXT("OHCI Driver InitializeAddresses: Failed!.\r\n"));
if (v_pDCPLLReg) VirtualFree((PVOID)v_pDCPLLReg,0,MEM_RELEASE);
if (v_pDCUSBReg) VirtualFree((PVOID)v_pDCUSBReg,0,MEM_RELEASE);
if (v_pDCIRQReg) VirtualFree((PVOID)v_pDCIRQReg,0,MEM_RELEASE);
if (v_pDCSMCReg) VirtualFree((PVOID)v_pDCSMCReg,0,MEM_RELEASE);
if (v_pOHCIDMABuffer) VirtualFree((PVOID)v_pOHCIDMABuffer,0,MEM_RELEASE);
v_pOHCIDMABuffer = 0;
v_pDCSMCReg = 0;
v_pDCUSBReg = 0;
v_pDCPLLReg = 0;
v_pDCIRQReg = 0;
return 0;
}
/* OhcdPdd_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 OhcdPdd_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 OhcdPdd_PowerUp(DWORD hDeviceContext)
{
SOhcdPdd * pPddObject = (SOhcdPdd *)hDeviceContext;
WRITE_BITFIELD(struct skpcrBITS,&v_pDCPLLReg->skpcr,UCLKEn,1); //Disable USB Clocks
OhcdMdd_PowerUp(pPddObject->lpvOhcdMddObject);
return;
}
extern void OhcdPdd_PowerDown(DWORD hDeviceContext)
{
SOhcdPdd * pPddObject = (SOhcdPdd *)hDeviceContext;
OhcdMdd_PowerDown(pPddObject->lpvOhcdMddObject);
WRITE_BITFIELD(struct skpcrBITS,&v_pDCPLLReg->skpcr,UCLKEn,0); //Disable USB Clocks
return;
}
extern BOOL OhcdPdd_Deinit(DWORD hDeviceContext)
{
SOhcdPdd * pPddObject = (SOhcdPdd *)hDeviceContext;
if(pPddObject->lpvOhcdMddObject)
OhcdMdd_DestroyOhcdObject(pPddObject->lpvOhcdMddObject);
if(pPddObject->lpvMemoryObject)
OhcdMdd_DestroyMemoryObject(pPddObject->lpvMemoryObject);
return TRUE;
}
extern DWORD OhcdPdd_Open(DWORD hDeviceContext, DWORD AccessCode,
DWORD ShareMode)
{
UnusedParameter(hDeviceContext);
UnusedParameter(AccessCode);
UnusedParameter(ShareMode);
return 1; // we can be opened, but only once!
}
extern BOOL OhcdPdd_Close(DWORD hOpenContext)
{
UnusedParameter(hOpenContext);
return TRUE;
}
extern DWORD OhcdPdd_Read(DWORD hOpenContext, LPVOID pBuffer, DWORD Count)
{
UnusedParameter(hOpenContext);
UnusedParameter(pBuffer);
UnusedParameter(Count);
return (DWORD)-1; // an error occured
}
extern DWORD OhcdPdd_Write(DWORD hOpenContext, LPCVOID pSourceBytes,
DWORD NumberOfBytes)
{
UnusedParameter(hOpenContext);
UnusedParameter(pSourceBytes);
UnusedParameter(NumberOfBytes);
return (DWORD)-1;
}
extern DWORD OhcdPdd_Seek(DWORD hOpenContext, LONG Amount, DWORD Type)
{
UnusedParameter(hOpenContext);
UnusedParameter(Amount);
UnusedParameter(Type);
return (DWORD)-1;
}
extern BOOL OhcdPdd_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;
}
VOID OHCI_Reset()
{
// go through USB initialization sequence SA-1111 TRM p. 6-1
//WRITE_BITFIELD(struct skpcrBITS,&v_pDCPLLReg->skpcr,DCLKEn,1); //Enable DMA Clocks
WRITE_BITFIELD(struct skpcrBITS,&v_pDCPLLReg->skpcr,UCLKEn,1); //Enable USB Clocks
usWait(10);
// Force reset
WRITE_BITFIELD(struct resetBITS,&v_pDCUSBReg->Reset,forceIfReset,1);
WRITE_BITFIELD(struct resetBITS,&v_pDCUSBReg->Reset,forceHcReset,1);
usWait(100);
WRITE_BITFIELD(struct resetBITS,&v_pDCUSBReg->Reset,forceIfReset,0);
WRITE_BITFIELD(struct resetBITS,&v_pDCUSBReg->Reset,forceHcReset,0);
WRITE_BITFIELD(struct resetBITS,&v_pDCUSBReg->Reset,clkGenReset,0);
WRITE_BITFIELD(struct resetBITS,&v_pDCUSBReg->Reset,pwrCtrlPolLow,1); // Need to invert the signal from the SA-1111 for the USB power controller
WRITE_BITFIELD(struct resetBITS,&v_pDCUSBReg->Reset,pwrSensePolLow,1);
WRITE_BITFIELD(struct skpcrBITS,&v_pDCPLLReg->skpcr,DCLKEn,1); //Enable DMA Clocks
NKDbgPrintfW(TEXT("OHCIPdd Init Interface Reset done +\r\n"));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -