/***************************************************************************
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;
}
Exemple #2
0
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;
}
Exemple #3
0
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;
}
Exemple #4
0
//=======================================================================
// 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));
}
Exemple #5
0
/* 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;
}
Exemple #6
0
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;
}