/*************************************************************************** Routine Description: This is the interrupt handler which is registered with the operating system. If several are pending (i.e. transmit complete and receive), handle them all. Block new interrupts until all pending interrupts are handled. Arguments: InterruptRecognized - Boolean value which returns TRUE if the ISR recognizes the interrupt as coming from this adapter. QueueDpc - TRUE if a DPC should be queued. Context - pointer to the adapter object Return Value: None. *****************************************************************************/ void R6040Isr( OUT PBOOLEAN InterruptRecognized, OUT PBOOLEAN QueueDpc, IN PVOID Context) { PR6040_ADAPTER Adapter = ((PR6040_ADAPTER)Context); //RETAILMSG(R6040DBG, (TEXT("R6040Isr()\r\n"))); // Force the INT signal from the chip low. When all // interrupts are acknowledged interrupts will be unblocked, KernelLibIoControl( Adapter->hISR, IOCTL_GIISR_PORTVALUE, NULL, 0x00, &Adapter->InterruptStatus, sizeof(USHORT), NULL); //RETAILMSG(R6040DBG, // (TEXT("R6040Isr(): Adapter->InterruptStatus : 0x%04x\r\n"), Adapter->InterruptStatus)); CardBlockInterrupts(Adapter); *InterruptRecognized = TRUE; *QueueDpc = TRUE; return; }
A_STATUS CF_UnMaskInterrupt(CF_DEVICE_HANDLE cfHandle) { CF_DEVICE *cfDevice; #ifndef POLL NDIS_STATUS ndisStatus; #endif HIF_DEBUG_PRINTF(ATH_LOG_TRC, "CF_UnMaskInterrupt \n"); cfDevice = (CF_DEVICE *)cfHandle; #ifdef POLL startPollThread(cfDevice); #else #ifdef SHARED_INTERRUPTS isrHandler = LoadIntChainHandler(TEXT("giisr.dll"),TEXT("ISRHandler"),(BYTE)cfDevice->interruptNumber); if (!isrHandler) { HIF_DEBUG_PRINTF(ATH_LOG_ERR,"CF_UnMaskInterrupt: Load int chain handler failed \n"); return A_ERROR; } memset (&Info,0,sizeof(Info)); Info.SysIntr = cfDevice->sysIntr; Info.CheckPort = TRUE; Info.PortIsIO = FALSE; Info.UseMaskReg = TRUE; Info.PortSize = sizeof(BYTE); Info.PortAddr = (DWORD)giisrMappedAddress + 0x00000400; Info.MaskAddr = (DWORD)giisrMappedAddress + 0x00000418; if (!KernelLibIoControl(isrHandler,IOCTL_GIISR_INFO,&Info,sizeof(Info),NULL,0,NULL)) { HIF_DEBUG_PRINTF(ATH_LOG_ERR,"CF_UnMaskInterrupt: KernelLibIoControl failed \n"); return A_ERROR; } #endif // SHARED_INTERRUPTS ndisStatus = NdisMRegisterInterrupt(&cfDevice->interruptObject, cfDevice->miniportHandle, cfDevice->interruptNumber, 0, TRUE, TRUE, 0); if (ndisStatus != NDIS_STATUS_SUCCESS) { return A_ERROR; } #endif cfDevice->interruptRegistered= TRUE; return A_OK; }
BOOL CSDHCBase::InitializeHardware( ) { SETFNAME(_T("InitializeHardware")); DEBUGCHK(m_hBusAccess); DEBUGCHK(m_regDevice.IsOK()); PREFAST_DEBUGCHK(m_pSlotInfos); RETAILMSG(0,(TEXT("CSDHCBase::InitializeHardware\n"))); ValidateSlotCount(); BOOL fRet = FALSE; PHYSICAL_ADDRESS PortAddress; DWORD inIoSpace = 0; // Read window information DDKWINDOWINFO wini; wini.cbSize = sizeof(wini); DWORD dwStatus = DDKReg_GetWindowInfo(m_regDevice, &wini); if (dwStatus != ERROR_SUCCESS) { DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s Error getting window information\r\n"), pszFname)); goto EXIT; } // Read ISR information DDKISRINFO isri; isri.cbSize = sizeof(isri); dwStatus = DDKReg_GetIsrInfo(m_regDevice, &isri); if (dwStatus != ERROR_SUCCESS) { DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s Error getting ISR information\r\n"), pszFname)); goto EXIT; } #ifdef SET_TI_BOARD_PCI_REG { DDKPCIINFO dpi; dpi.cbSize = sizeof(dpi); DDKReg_GetPciInfo(m_regDevice, &dpi); DWORD RetVal; PCI_SLOT_NUMBER SlotNumber; SlotNumber.u.AsULONG = 0; SlotNumber.u.bits.DeviceNumber = dpi.dwDeviceNumber; SlotNumber.u.bits.FunctionNumber = 1; HalGetBusDataByOffset( PCIConfiguration, wini.dwBusNumber, SlotNumber.u.AsULONG, &RetVal, 0x84, sizeof( RetVal ) ); if (!(RetVal & 0x00200000)) { RetVal |= 0x00200000; HalSetBusDataByOffset( PCIConfiguration, wini.dwBusNumber, SlotNumber.u.AsULONG, &RetVal, 0x84, sizeof( RetVal ) ); } } #endif // Sanity check ISR if (isri.dwSysintr == SYSINTR_NOP) { RETAILMSG(0,(TEXT("%s No sysintr specified in registry\r\n"),pszFname)); DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s No sysintr specified in registry\r\n"), pszFname)); goto EXIT; } if (isri.szIsrDll[0] != 0) { if ( (isri.szIsrHandler[0] == 0) || (isri.dwIrq == IRQ_UNSPECIFIED) ) { DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s Invalid installable ISR information in registry\r\n"), pszFname)); goto EXIT; } } m_interfaceType = (INTERFACE_TYPE) wini.dwInterfaceType; m_dwBusNumber = wini.dwBusNumber; DWORD dwSlotZeroWindow; dwSlotZeroWindow = DetermineFirstSlotWindow(&wini); DEBUGCHK(dwSlotZeroWindow < wini.dwNumMemWindows); DEBUGCHK( (dwSlotZeroWindow + m_cSlots) <= wini.dwNumMemWindows ); // Use the slot zero window for the ISR PDEVICEWINDOW pWindowSlotZero = &wini.memWindows[dwSlotZeroWindow]; PortAddress.LowPart = pWindowSlotZero->dwBase; PortAddress.HighPart = 0; RETAILMSG(0,(TEXT("CSDHCBase::InitializeHardware go on...\n"))); // Install an ISR, if present if (isri.szIsrDll[0] != 0) { m_hISRHandler = LoadIntChainHandler(isri.szIsrDll, isri.szIsrHandler, (BYTE) isri.dwIrq); if (m_hISRHandler == NULL) { DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s Error installing ISR\r\n"), pszFname)); goto EXIT; } else { GIISR_INFO Info; DWORD dwPhysAddr; fRet = BusTransBusAddrToStatic(m_hBusAccess, (INTERFACE_TYPE) wini.dwInterfaceType, wini.dwBusNumber, PortAddress, pWindowSlotZero->dwLen, &inIoSpace, (PVOID *) &dwPhysAddr); if (fRet == FALSE) { DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s Error translating bus address to static address\r\n"), pszFname)); goto EXIT; } // Initialize ISR Info.SysIntr = isri.dwSysintr; Info.CheckPort = TRUE; Info.PortIsIO = (inIoSpace != 0); Info.UseMaskReg = FALSE; Info.PortAddr = dwPhysAddr + SDHC_SLOT_INT_STATUS; Info.PortSize = sizeof(USHORT); Info.Mask = 0xFF; fRet = KernelLibIoControl(m_hISRHandler, IOCTL_GIISR_INFO, &Info, sizeof(Info), NULL, 0, NULL); if (fRet == FALSE) { DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s Error setting up ISR\r\n"), pszFname)); goto EXIT; } } } m_dwSysIntr = isri.dwSysintr; DEBUGMSG(SDCARD_ZONE_INIT, (_T("%s IRQ 0x%X mapped to SYS_INTR 0x%X\r\n"), pszFname, isri.dwIrq, m_dwSysIntr)); const DWORD dwEndWindow = dwSlotZeroWindow + m_cSlots; for (DWORD dwWindow = dwSlotZeroWindow; dwWindow < dwEndWindow; ++dwWindow) { DEBUGCHK(dwWindow < wini.dwNumMemWindows); PDEVICEWINDOW pWindowSD = &wini.memWindows[dwWindow]; DEBUGMSG(SDCARD_ZONE_INIT, (_T("%s Base address -> 0x%x; length -> 0x%x \r\n"), pszFname, pWindowSD->dwBase, pWindowSD->dwLen)); PortAddress.LowPart = pWindowSD->dwBase; PortAddress.HighPart = 0; inIoSpace = 0; PVOID pvRegisters; DEBUGCHK(pWindowSlotZero->dwLen >= sizeof(SSDHC_REGISTERS)); RETAILMSG(0,(TEXT("BusTransBusAddrToVirtual. 0x%X\n"),PortAddress)); fRet = BusTransBusAddrToVirtual(m_hBusAccess, (INTERFACE_TYPE) wini.dwInterfaceType, wini.dwBusNumber, PortAddress, pWindowSD->dwLen, &inIoSpace, &pvRegisters); if (fRet == FALSE) { RETAILMSG(0,(TEXT("%s error translating SD address \r\n"),pszFname)); DEBUGMSG(SDCARD_ZONE_ERROR, (_T("%s error translating SD address \r\n"), pszFname)); goto EXIT; } DEBUGCHK(inIoSpace == 0); // Will not work for I/O mappings. DWORD dwSlot = dwWindow - dwSlotZeroWindow; DEBUGCHK(dwSlot < m_cSlots); m_pSlotInfos[dwSlot].pucRegisters = (volatile UCHAR*) pvRegisters; m_pSlotInfos[dwSlot].dwExtraInfo = pWindowSD->dwLen; } m_fHardwareInitialized = TRUE; fRet = TRUE; RETAILMSG(0,(TEXT("CSDHCBase::InitializeHardware finished.\n"))); EXIT: return fRet; }
//======================================================================= // LED_Init - Driver initialization function // DWORD LED_Init(LPCSTR pContext, DWORD dwBusContext){ PDRVCONTEXT pDrv; RETAILMSG(RETAIL_ON, (TEXT("Test debug output without context \r\n"))); RETAILMSG(RETAIL_ON, (TEXT("LED_Init++ dwContext: %x\r\n"), pContext)); // Allocate a driver instance structure - required if we want to manage // more instances pDrv = (PDRVCONTEXT)LocalAlloc(LPTR, sizeof(DRVCONTEXT)); if(pDrv){ // initialize structure memset((PBYTE) pDrv, 0, sizeof(DRVCONTEXT)); pDrv->dwSize = sizeof(DRVCONTEXT); // read registry to determine the size of the disk // GetConfigData((DWORD)pContext); }else{ RETAILMSG(RETAIL_ON, (DTAG TEXT("LED_Init failure. Out of memory\r\n"), pContext)); } DWORD dwGpio = 15; DWORD dwIrq = 0; DWORD dwEdge = GPIO_EDGE_RISING; if (!KernelIoControl(IOCTL_HAL_GPIO2IRQ, &dwGpio, sizeof(DWORD), &dwIrq, sizeof(DWORD), NULL)) { RETAILMSG(RETAIL_ON, (DTAG TEXT("LED_Init failure. IOCTL_HAL_GPIO2IRQ\r\n"), pContext)); return 0; } if (!KernelIoControl(IOCTL_HAL_IRQEDGE, &dwIrq, sizeof(BYTE), &dwEdge, sizeof(BYTE), NULL)) { RETAILMSG(RETAIL_ON, (DTAG TEXT("LED_Init failure. IOCTL_HAL_IRQEDGE\r\n"), pContext)); return 0; } if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &dwIrq, sizeof(DWORD), &(pDrv->dwSysIntr), sizeof(DWORD), NULL)) { RETAILMSG(RETAIL_ON, (DTAG TEXT("LED_Init failure. IOCTL_HAL_REQUEST_SYSINTR\r\n"), pContext)); return 0; } pDrv->hEvent = CreateEvent(NULL, false, false, TEXT("ISTEvent")); if (!(pDrv->hEvent)) { RETAILMSG(RETAIL_ON, (DTAG TEXT("LED_Init failure. Create Event failed.\r\n"), pContext)); return 0; } if (!InterruptInitialize(pDrv->dwSysIntr, pDrv->hEvent, NULL, 0)) { RETAILMSG(RETAIL_ON, (DTAG TEXT("LED_Init failure. InterruptInitialize failed.\r\n"), pContext)); return 0; } pDrv->hIsrHandle = LoadIntChainHandler(TEXT("\\Program Files\\Drivers\\ISRDll.dll"), TEXT("ISRHandler"), dwIrq); if (!pDrv->hIsrHandle) { RETAILMSG(RETAIL_ON, (DTAG TEXT("LED_Init failure. LoadIntChainHandler failed.\r\n"), pContext)); return 0; } isr_info.SysIntr = pDrv->dwSysIntr; isr_info.pGPIORegs = (GPIOREG*)CreateStaticMapping(GPIO_BASE >> 8, sizeof(GPIOREG)); if (!isr_info.pGPIORegs) { RETAILMSG(RETAIL_ON, (DTAG TEXT("LED_Init failure. CreateStaticMapping failed.\r\n"), pContext)); return 0; } if (!KernelLibIoControl(pDrv->hIsrHandle, IOCTL_ISR_INFO, &isr_info, sizeof(isr_info), NULL, 0, NULL)) { RETAILMSG(RETAIL_ON, (DTAG TEXT("LED_Init failure. IOCTL_HAL_RELEASE_SYSINTR failed.\r\n"), pContext)); return 0; } pDrv->hIntThread = CreateThread(NULL, 0, ISTFunction, pDrv->hEvent, 0, NULL); if (!pDrv->hIntThread) { RETAILMSG(RETAIL_ON, (DTAG TEXT("LED_Init failure. CreateThread failed.\r\n"), pContext)); return 0; } RETAILMSG(RETAIL_ON, (DTAG TEXT("LED_Init-- pDrv: %x\r\n"), pDrv)); return (DWORD)pDrv; FREECHAINHANDLER: FreeIntChainHandler(pDrv->hIsrHandle); INTERRUPTDISABLE: InterruptDisable(pDrv->dwSysIntr); KERNELIOCONTROL: KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &pDrv->dwSysIntr, sizeof(DWORD), NULL, 0, NULL); CLOSEHANDLE: CloseHandle(pDrv->hEvent); DELETESTATICMAPPING: DeleteStaticMapping((LPVOID)isr_info.pGPIORegs, sizeof(GPIOREG)); }
/* 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 { PUCHAR ioPortBase = NULL; DWORD dwAddrLen; DWORD dwIOSpace; BOOL InstallIsr = FALSE; BOOL fResult = FALSE; LPVOID pobMem = NULL; LPVOID pobOhcd = NULL; DWORD PhysAddr; DWORD dwHPPhysicalMemSize; HKEY hKey=NULL; DDKWINDOWINFO dwi; DDKISRINFO dii; USBH_MSG((_T("[USBH] ++InitializeOHCI()\n\r"))); g_pSysConReg = (S3C6410_SYSCON_REG *)DrvLib_MapIoSpace(S3C6410_BASE_REG_PA_SYSCON, sizeof(S3C6410_SYSCON_REG), FALSE); if (g_pSysConReg == NULL) { USBH_ERR((_T("[USBH:ERR] InitializeOHCI() : DrvLib_MapIoSpace() Failed\n"))); return FALSE; } #ifdef USE_SRCCLK_EPLL //----------------------- // Initialize Clock // ClkSrc = MOUT_EPLL (96MHz) // Divide by 2 (96/2=48MHz) // HCLK, SCLK gate pass //----------------------- g_pSysConReg->CLK_SRC = (g_pSysConReg->CLK_SRC & ~(0x3<<5)) | (0x1<<5); // UHOST_SEL : MoutEPLL g_pSysConReg->CLK_DIV1 = (g_pSysConReg->CLK_DIV1 & ~(0xf<<20)) | (0x1<<20); // UHOST_RATIO : 96 MHz / (1+1) = 48 MHz #else //----------------------- // Initialize Clock // ClkSrc = USB_PHY(48MHz) // Divide by 1 (48/1=48MHz) // HCLK, SCLK gate pass //----------------------- g_pSysConReg->OTHERS |= (1<<16); // Set SUB Signal Mask g_pSysConReg->CLK_SRC &= ~(0x3<<5); // UHOST_SEL : 48MHz g_pSysConReg->CLK_DIV1 &= ~(0xf<<20); // UHOST_RATIO : 48 MHz / (0+1) = 48 MHz #endif g_pSysConReg->HCLK_GATE |= (0x1<<29); // HCLK_UHOST Pass (EVT1) g_pSysConReg->SCLK_GATE |= (0x1<<30); // SCLK_UHOST Pass if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,szDriverRegKey,0,0,&hKey)!= ERROR_SUCCESS) { DEBUGMSG(ZONE_ERROR,(TEXT("InitializeOHCI:GetRegistryConfig RegOpenKeyEx(%s) failed\r\n"), szDriverRegKey)); return FALSE; } dwi.cbSize=sizeof(dwi); dii.cbSize=sizeof(dii); if ( (DDKReg_GetWindowInfo(hKey, &dwi ) != ERROR_SUCCESS) || (DDKReg_GetIsrInfo (hKey, &dii ) != ERROR_SUCCESS)) { DEBUGMSG(ZONE_ERROR,(TEXT("InitializeOHCI:DDKReg_GetWindowInfo or DDKReg_GetWindowInfo failed\r\n"))); goto InitializeOHCI_Error; } if (dwi.dwNumMemWindows!=0) { PhysAddr = dwi.memWindows[0].dwBase; dwAddrLen= dwi.memWindows[0].dwLen; dwIOSpace = 0; } else if (dwi.dwNumIoWindows!=0) { PhysAddr= dwi.ioWindows[0].dwBase; dwAddrLen = dwi.ioWindows[0].dwLen; dwIOSpace = 1; } else { goto InitializeOHCI_Error; } DEBUGMSG(ZONE_INIT,(TEXT("OHCD: Read config from registry: Base Address: 0x%X, Length: 0x%X, I/O Port: %s, SysIntr: 0x%X, Interface Type: %u, Bus Number: %u\r\n"), PhysAddr, dwAddrLen, dwIOSpace ? L"YES" : L"NO", dii.dwSysintr, dwi.dwInterfaceType, dwi.dwBusNumber)); ioPortBase = (PBYTE) PhysAddr; if (!(fResult = ConfigureOHCICard(pPddObject, &ioPortBase, dwAddrLen, dwIOSpace,(INTERFACE_TYPE)dwi.dwInterfaceType, dwi.dwBusNumber))) { goto InitializeOHCI_Error; } if (dii.szIsrDll[0] != 0 && dii.szIsrHandler[0]!=0 && dii.dwIrq<0xff && dii.dwIrq>0 ) { // Install ISR handler pPddObject->IsrHandle = LoadIntChainHandler(dii.szIsrDll, dii.szIsrHandler, (BYTE)dii.dwIrq); if (!pPddObject->IsrHandle) { DEBUGMSG(ZONE_ERROR, (L"OHCD: Couldn't install ISR handler\r\n")); } else { GIISR_INFO Info; PHYSICAL_ADDRESS PortAddress = {PhysAddr, 0}; DEBUGMSG(ZONE_INIT, (L"OHCD: Installed ISR handler, Dll = '%s', Handler = '%s', Irq = %d\r\n", dii.szIsrDll, dii.szIsrHandler, dii.dwIrq)); if (!BusTransBusAddrToStatic(pPddObject->hParentBusHandle,(INTERFACE_TYPE)dwi.dwInterfaceType, dwi.dwBusNumber, PortAddress, dwAddrLen, &dwIOSpace, (PPVOID)&PhysAddr)) { DEBUGMSG(ZONE_ERROR, (L"OHCD: Failed TransBusAddrToStatic\r\n")); goto InitializeOHCI_Error; } // Set up ISR handler Info.SysIntr = dii.dwSysintr; Info.CheckPort = TRUE; Info.PortIsIO = (dwIOSpace) ? TRUE : FALSE; Info.UseMaskReg = TRUE; Info.PortAddr = PhysAddr + 0x0C; Info.PortSize = sizeof(DWORD); Info.MaskAddr = PhysAddr + 0x10; if (!KernelLibIoControl(pPddObject->IsrHandle, IOCTL_GIISR_INFO, &Info, sizeof(Info), NULL, 0, NULL)) { DEBUGMSG(ZONE_ERROR, (L"OHCD: KernelLibIoControl call failed.\r\n")); } } } // The PDD can supply a buffer of contiguous physical memory here, or can let the // MDD try to allocate the memory from system RAM. We will use the HalAllocateCommonBuffer() // API to allocate the memory and bus controller physical addresses and pass this information // into the MDD. if (GetRegistryPhysicalMemSize(szDriverRegKey,&pPddObject->dwPhysicalMemSize)) { // A quarter for High priority Memory. dwHPPhysicalMemSize = pPddObject->dwPhysicalMemSize/4; // Align with page size. pPddObject->dwPhysicalMemSize = (pPddObject->dwPhysicalMemSize + PAGE_SIZE -1) & ~(PAGE_SIZE -1); dwHPPhysicalMemSize = ((dwHPPhysicalMemSize + PAGE_SIZE -1) & ~(PAGE_SIZE -1)); } else { pPddObject->dwPhysicalMemSize=0; dwHPPhysicalMemSize = 0 ; } if (pPddObject->dwPhysicalMemSize<gcTotalAvailablePhysicalMemory) { // Setup Minimun requirement. pPddObject->dwPhysicalMemSize = gcTotalAvailablePhysicalMemory; dwHPPhysicalMemSize = gcHighPriorityPhysicalMemory; } pPddObject->AdapterObject.ObjectSize = sizeof(DMA_ADAPTER_OBJECT); pPddObject->AdapterObject.InterfaceType = dwi.dwInterfaceType; pPddObject->AdapterObject.BusNumber = dwi.dwBusNumber; if ((pPddObject->pvVirtualAddress = HalAllocateCommonBuffer(&pPddObject->AdapterObject, pPddObject->dwPhysicalMemSize, &pPddObject->LogicalAddress, FALSE)) == NULL) { goto InitializeOHCI_Error; } if (!(pobMem = HcdMdd_CreateMemoryObject(pPddObject->dwPhysicalMemSize, dwHPPhysicalMemSize, (PUCHAR) pPddObject->pvVirtualAddress, (PUCHAR) pPddObject->LogicalAddress.LowPart))) { goto InitializeOHCI_Error; } if (!(pobOhcd = HcdMdd_CreateHcdObject(pPddObject, pobMem, szDriverRegKey, ioPortBase, dii.dwSysintr))) { goto InitializeOHCI_Error; } pPddObject->lpvMemoryObject = pobMem; pPddObject->lpvOhcdMddObject = pobOhcd; _tcsncpy(pPddObject->szDriverRegKey, szDriverRegKey, MAX_PATH); pPddObject->ioPortBase = ioPortBase; pPddObject->dwSysIntr = dii.dwSysintr; // PCI OHCI support suspend and resume if ( hKey!=NULL) { DWORD dwCapability; DWORD dwType; DWORD dwLength = sizeof(DWORD); if (RegQueryValueEx(hKey, HCD_CAPABILITY_VALNAME, 0, &dwType, (PUCHAR)&dwCapability, &dwLength) == ERROR_SUCCESS) { HcdMdd_SetCapability(pobOhcd, dwCapability); USBH_INF((_T("[USBH:INF] InitializeOHCI() : USB Host Cap : 0x%08x\n"), dwCapability)); } RegCloseKey(hKey); } USBH_MSG((_T("[USBH] --InitializeOHCI() : Success\n\r"))); return TRUE; InitializeOHCI_Error: if (g_pSysConReg != NULL) { DrvLib_UnmapIoSpace((PVOID)g_pSysConReg); g_pSysConReg = NULL; } if (pPddObject->IsrHandle) { FreeIntChainHandler(pPddObject->IsrHandle); pPddObject->IsrHandle = NULL; } if (pobOhcd) { HcdMdd_DestroyHcdObject(pobOhcd); } if (pobMem) { HcdMdd_DestroyMemoryObject(pobMem); } if(pPddObject->pvVirtualAddress) { HalFreeCommonBuffer(&pPddObject->AdapterObject, pPddObject->dwPhysicalMemSize, pPddObject->LogicalAddress, pPddObject->pvVirtualAddress, FALSE); } pPddObject->lpvMemoryObject = NULL; pPddObject->lpvOhcdMddObject = NULL; pPddObject->pvVirtualAddress = NULL; if ( hKey!=NULL) { RegCloseKey(hKey); } USBH_ERR((_T("[USBH:ERR] --InitializeOHCI() : Error\n\r"))); return FALSE; }
EXTERN_C DWORD WINAPI PlatformSetSystemPowerState (LPCTSTR pszName, BOOL fForce, BOOL fInternal) { DWORD dwStatus = ERROR_SUCCESS; PSYSTEM_POWER_STATE pNewSystemPowerState = NULL; PDEVICE_POWER_RESTRICTION pNewCeilingDx = NULL; BOOL fDoTransition = FALSE; INT iPreSuspendPriority = 0; static BOOL fFirstCall = TRUE; SETFNAME (_T ("PlatformSetSystemPowerState")); // Read system power state variables and construct new lists: if (gfFileSystemsAvailable) PmUpdateSystemPowerStatesIfChanged (); dwStatus = RegReadSystemPowerState (pszName, &pNewSystemPowerState, &pNewCeilingDx); // Did we get registry information about the new power state? if (dwStatus == ERROR_SUCCESS) { BOOL fSuspendSystem = FALSE; static BOOL fWantStartupScreen = FALSE; DWORD dwNewStateFlags = pNewSystemPowerState->dwFlags; // Assume we will update the system power state: fDoTransition = TRUE; // Are we going to suspend the system as a whole? if ((dwNewStateFlags & (POWER_STATE_SUSPEND | POWER_STATE_OFF | POWER_STATE_CRITICAL | POWER_STATE_RESET)) != 0) { fSuspendSystem = TRUE; } // A "critical" suspend might mean we have totally lost battery power and need // to suspend really quickly. Depending on the platform, OEMs may be able // to bypass driver notification entirely and rely on xxx_PowerDown() notifications // to suspend gracefully. Or they may be able to implement a critical suspend // kernel ioctl. This sample implementation is very generic and simply sets the // POWER_FORCE flag, which is not used. if (dwNewStateFlags & (POWER_STATE_CRITICAL | POWER_STATE_OFF | POWER_STATE_RESET)) { fForce = TRUE; } // If everything seems OK, do the set operation: if (fDoTransition) { POWER_BROADCAST_BUFFER pbb; PDEVICE_LIST pdl; BOOL fResumeSystem = FALSE; // Send out system power state change notifications: pbb.Message = PBT_TRANSITION; pbb.Flags = pNewSystemPowerState->dwFlags; pbb.Length = _tcslen (pNewSystemPowerState->pszName) + 1; // Char count not byte count for now if (pbb.Length > MAX_PATH) { // Truncate the system power state name -- note, we actually have MAX_PATH + 1 // characters available. pbb.Length = MAX_PATH; } _tcsncpy_s (pbb.SystemPowerState, _countof (pbb.SystemPowerState), pNewSystemPowerState->pszName, pbb.Length); pbb.Length *= sizeof (pbb.SystemPowerState[0]); // Convert to byte count GenerateNotifications ((PPOWER_BROADCAST) & pbb); // Is GWES ready? if (!gfGwesReady) { if (WaitForAPIReady (SH_GDI, 0) == WAIT_OBJECT_0) { gfGwesReady = TRUE; } } // Are we suspending? if (fSuspendSystem && gpfnGwesPowerDown != NULL) { // Start the process of suspending GWES: if (gfGwesReady) { fWantStartupScreen = gpfnGwesPowerDown (); } } // Update global system state variables: PMLOCK (); PSYSTEM_POWER_STATE pOldSystemPowerState = gpSystemPowerState; PDEVICE_POWER_RESTRICTION pOldCeilingDx = gpCeilingDx; if (gpSystemPowerState != NULL && (gpSystemPowerState-> dwFlags & (POWER_STATE_SUSPEND | POWER_STATE_OFF | POWER_STATE_CRITICAL)) != 0) { // We are exiting a suspended state: fResumeSystem = TRUE; } gpSystemPowerState = pNewSystemPowerState; gpCeilingDx = pNewCeilingDx; PMUNLOCK (); // Are we suspending, resuming, or neither? if (fSuspendSystem) { INT iCurrentPriority; // We're suspending: update all devices other than block devices, // in case any of them need to access the registry or write files. PMLOGMSG (ZONE_PLATFORM || ZONE_RESUME, (_T ("%s: suspending - notifying non-block drivers\r\n"), pszFname)); for (pdl = gpDeviceLists; pdl != NULL; pdl = pdl->pNext) { if (*pdl->pGuid != idBlockDevices) { UpdateClassDeviceStates (pdl); } } // Notify the kernel that we are about to suspend. This gives the // kernel an opportunity to clear wake source flags before we initiate // the suspend process. If we don't do this and a wake source interrupt // occurs between the time we call PowerOffSystem() and the time // OEMPowerOff() is invoked, it is hard for the kernel to know whether or // not to suspend. PMLOGMSG (ZONE_PLATFORM || ZONE_RESUME, (_T ("%s: calling KernelIoControl(IOCTL_HAL_PRESUSPEND)\r\n"), pszFname)); KernelIoControl (IOCTL_HAL_PRESUSPEND, NULL, 0, NULL, 0, NULL); iCurrentPriority = CeGetThreadPriority (GetCurrentThread ()); DEBUGCHK (iCurrentPriority != THREAD_PRIORITY_ERROR_RETURN); if (iCurrentPriority != THREAD_PRIORITY_ERROR_RETURN) { CeSetThreadPriority (GetCurrentThread (), giPreSuspendPriority); Sleep (0); CeSetThreadPriority (GetCurrentThread (), iCurrentPriority); } // Notify file systems that their block drivers will soon go away. // After making this call, this thread is the only one that can access // the file system (including registry and device drivers) without // blocking. Unfortunately, this API takes and holds the file system // critical section, so other threads attempting to access the registry // or files may cause priority inversions. To avoid priority problem // that may starve the Power Manager, we may raise our own priority to a // high level. Do this if giSuspendPriority is non-zero. if (giSuspendPriority != 0) { iPreSuspendPriority = CeGetThreadPriority (GetCurrentThread ()); DEBUGCHK (iPreSuspendPriority != THREAD_PRIORITY_ERROR_RETURN); PMLOGMSG (ZONE_PLATFORM, (_T ("%s: suspending: raising thread priority for 0x%08x from %d to %d\r\n"), pszFname, GetCurrentThreadId (), iPreSuspendPriority, giSuspendPriority)); CeSetThreadPriority (GetCurrentThread (), giSuspendPriority); } // Discard code pages from drivers. This is a diagnostic tool to // forcibly expose paging-related bugs that could cause apparently // random system crashes or hangs. Optionally, OEMs can disable this // for production systems to speed up resume times. We have to call // PageOutMode before FileSys Shutdown. Otherwise, it cause dead lock // between filesystem and loader. if (gfPageOutAllModules) { ForcePageout (); } if (g_pSysRegistryAccess) g_pSysRegistryAccess->EnterLock (); gfFileSystemsAvailable = FALSE; if ((dwNewStateFlags & POWER_STATE_RESET) != 0) { // Is this to be a cold boot? if (_tcscmp (pszName, _T ("coldreboot")) == 0) { SetCleanRebootFlag (); } } FileSystemPowerFunction (FSNOTIFY_POWER_OFF); // Update block device power states: PMLOGMSG (ZONE_PLATFORM || ZONE_RESUME, (_T ("%s: suspending - notifying block drivers\r\n"), pszFname)); pdl = GetDeviceListFromClass (&idBlockDevices); if (pdl != NULL) { UpdateClassDeviceStates (pdl); } // Handle resets and shutdowns here, after flushing files. Since Windows CE does // not define a standard mechanism for handling shutdown (via POWER_STATE_OFF), // OEMs will need to fill in the appropriate code here. Similarly, if an OEM does // not support IOCTL_HAL_REBOOT, they should not support POWER_STATE_RESET. if ((dwNewStateFlags & POWER_STATE_RESET) != 0) { // Should not return from this call, but if we do just suspend the system: KernelLibIoControl ((HANDLE) KMOD_OAL, IOCTL_HAL_REBOOT, NULL, 0, NULL, 0, NULL); RETAILMSG (TRUE, (_T ("PM: PlatformSetSystemPowerState: KernelIoControl(IOCTL_HAL_REBOOT) returned!\r\n"))); DEBUGCHK (FALSE); // Break into the debugger. } } else if (fResumeSystem) { // We're waking up from a resume -- update block device power states // so we can access the registry and/or files. PMLOGMSG (ZONE_PLATFORM || ZONE_RESUME, (_T ("%s: resuming - notifying block drivers\r\n"), pszFname)); pdl = GetDeviceListFromClass (&idBlockDevices); if (pdl != NULL) { UpdateClassDeviceStates (pdl); } // Notify file systems that their block drivers are back. FileSystemPowerFunction (FSNOTIFY_POWER_ON); gfFileSystemsAvailable = TRUE; if (g_pSysRegistryAccess) g_pSysRegistryAccess->LeaveLock (); // Update all devices other than block devices: PMLOGMSG (ZONE_PLATFORM || ZONE_RESUME, (_T ("%s: resuming - notifying block drivers\r\n"), pszFname)); for (pdl = gpDeviceLists; pdl != NULL; pdl = pdl->pNext) { if (*pdl->pGuid != idBlockDevices) { UpdateClassDeviceStates (pdl); } } // Tell GWES to wake up: if (gpfnGwesPowerUp != NULL && gfGwesReady) { gpfnGwesPowerUp (fWantStartupScreen); fWantStartupScreen = FALSE; } // Send out resume notification: pbb.Message = PBT_RESUME; pbb.Flags = 0; pbb.Length = 0; pbb.SystemPowerState[0] = 0; GenerateNotifications ((PPOWER_BROADCAST) & pbb); } else { // Update all devices without any particular ordering: UpdateAllDeviceStates (); } // Release the old state information: SystemPowerStateDestroy (pOldSystemPowerState); while (pOldCeilingDx != NULL) { PDEVICE_POWER_RESTRICTION pdpr = pOldCeilingDx->pNext; PowerRestrictionDestroy (pOldCeilingDx); pOldCeilingDx = pdpr; } // Are we suspending? if (fSuspendSystem) { // Set a flag to notify the resume thread that this was a controlled suspend. gfSystemSuspended = TRUE; PMLOGMSG (ZONE_PLATFORM || ZONE_RESUME, (_T ("%s: calling PowerOffSystem()\r\n"), pszFname)); PowerOffSystem (); // Sets a flag in the kernel for the scheduler. Sleep (0); // Force the scheduler to run. PMLOGMSG (ZONE_PLATFORM || ZONE_RESUME, (_T ("%s: back from PowerOffSystem()\r\n"), pszFname)); // Clear the suspend flag: gfSystemSuspended = FALSE; } } else { // Release the unused new state information: SystemPowerStateDestroy (pNewSystemPowerState); while (pNewCeilingDx != NULL) { PDEVICE_POWER_RESTRICTION pdpr = pNewCeilingDx->pNext; PowerRestrictionDestroy (pNewCeilingDx); pNewCeilingDx = pdpr; } } } // Restore our priority if we updated it during a suspend transition: if (giSuspendPriority != 0 && iPreSuspendPriority != 0) { PMLOGMSG (ZONE_PLATFORM, (_T ("%s: restoring thread priority to %d\r\n"), pszFname, iPreSuspendPriority)); CeSetThreadPriority (GetCurrentThread (), iPreSuspendPriority); } return dwStatus; }